我希望有一个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子句)非常容易实现且非常有用,但由于某种原因它不包括在内。
答案 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表中插入虚拟记录