用于生成序列号的SQL Server函数

时间:2011-08-17 14:54:45

标签: sql-server sqlclr sequences clr-hosting

我希望有一个SQL Server函数dbo.GetNextNumber(),它会为每个调用生成序列号。据我所知,使用本机T-SQL函数是不可能的,因为SQL Server坚持认为函数必须是确定性的。但是,如果你能告诉我一个原生的T-SQL函数,那么这真的会让我感到非常重要。

我想也许可以使用CLR函数编写。由于CLR函数是静态的,序列号需要存储在set操作的调用上下文中,因为将其存储为静态变量将导致使用相同序列的多个连接,从而导致不那么顺序的数字。我对嵌入式CLR知之甚少,看看是否可以从CLR端访问set操作(select,update,delete,insert)调用上下文。

在一天结束时,以下查询

select dbo.GetNextNumber() from sysobjects

必须返回结果

1
2
3
4
5

如果需要另一个函数调用来重置上下文,那就没关系了,如

exec dbo.ResetSequenceNumbers()

为了防止一些误解并减少浪费时间回答错误问题的机会,请注意我不是在寻找桌面的ID生成功能而且我知道一些黑客攻击(虽然使用了proc而不是函数)涉及一些带有标识列的临时表。 ROW_NUMBER()功能很接近,但也没有削减。

非常感谢任何回复

末尔

P.S。令人惊讶的是,SQL Server确实具有内置功能。一个函数(假设它不能用于连接和where子句)非常容易实现且非常有用,但由于某种原因它不包括在内。

4 个答案:

答案 0 :(得分:5)

根据我与运行总计计算相关的文章实施CLR序列,您可以使用 ROW_NUBER() 功能实现相同目标。

ROW_NUMBER()函数需要ORDER BY子句中的OVER,但是有一个很好的解决方法,如何避免由ORDER BY引起的排序。您不能按顺序放置表达式,但可以将SELECT aConstant放在那里。因此,您可以使用以下语句轻松实现数字生成。

SELECT
    ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNumber,
    *
FROM aTable

答案 1 :(得分:2)

在下一版本的SQL Server中,您可以使用SEQUENCE执行此操作。在早期版本中,通过插入单独的“序列表”(仅具有IDENTITY列的表)然后使用SCOPE_IDENTITY()函数检索值,可以轻松完成。您将无法在函数中执行此操作,但可以使用存储过程。

答案 2 :(得分:2)

您能否提供有关ROW_NUMBER()未切割原因的更多信息?在您提供的具体示例中,ROW_NUMBER()(适当澄清OVER(ORDER BY))肯定符合您的标准。

但肯定存在ROW_NUMBER()可能没用的情况,在这种情况下,通常还有其他技术。

也许拥有这个通用功能对你来说似乎很有用,但在大多数情况下,我发现更适合手头问题的解决方案比通用功能更好,最终导致更多困难 - 比如漏你抽象你一直在努力。您特别提到需要重置功能。 ROW_NUMBER()不需要这样的事情,因为它有OVER(PARTITION BY ORDER BY)允许您指定分组。

答案 3 :(得分:0)

SQL Server Denali为开发人员提供了一个新的序列结构 在Denali之后,很容易在SQL Server中管理和维护序列号 您可以在Sequence Numbers in SQL Server

中找到详细信息

对于除Denali之外的其他版本,您可以使用序列表。 以下是Sequence Table in SQL Server的示例 要从序列表中读取序列号,您应该从此启用自动身份的sql表中插入虚拟记录