一个SQL Server函数,用于生成序列号



我想有一个SQL Server函数dbo.GetNextNumber(),它将为每次调用生成序列号。据我所知,这对于本地的T-SQL函数是不可能的,因为SQL Server坚持函数必须是确定性的。但是,如果你能给我展示一个本地的T-SQL函数来做这个,我会很高兴的。

我想也许可以使用CLR函数来编写。由于CLR函数是静态的,因此需要将序列号存储在set操作的调用上下文中,因为将其存储为静态变量将导致使用相同序列的多个连接,从而导致不那么连续的数字。我对嵌入式CLR了解不够,无法查看是否可以从CLR端访问设置操作(选择,更新,删除,插入)调用上下文。

在一天结束时,以下查询

select dbo.GetNextNumber() from sysobjects

必须返回结果

1
2
3
4
5

如果需要另一个函数调用来重置上下文(如

),则可以。
exec dbo.ResetSequenceNumbers()

为了防止一些误解并减少浪费时间回答错误问题的机会,请注意,我不是在寻找表的ID生成函数,并且我知道一些hack(尽管使用进程而不是函数)涉及一些具有身份列的临时表。ROW_NUMBER()功能闭合,但也不切断。

非常感谢您的回复

凯末尔

注:令人惊讶的是,SQL Server确实有一个内置的功能。一个函数(前提是它不能在join和where子句中使用)确实很容易实现并且非常有用,但由于某些原因,它没有被包含在内。

由于您已经根据我的有关计算运行总数的文章实现了CLR序列,因此您可以使用 ROW_NUBER() 函数实现相同的目的。

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

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

在SQL Server的下一个版本中,您可以使用SEQUENCE来完成此操作。在早期版本中,通过插入到一个单独的"序列表"(一个只有IDENTITY列的表),然后使用SCOPE_IDENTITY()函数检索值,就可以很容易地做到这一点。您不能在函数中这样做,但可以使用存储过程。

你能给更多的信息为什么ROW_NUMBER()不能削减它吗?在你给出的具体例子中,ROW_NUMBER()(对OVER(ORDER BY)进行适当的澄清)似乎当然符合你的标准。

但在某些情况下,ROW_NUMBER()可能没有用处,在这些情况下,通常有其他技术。

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

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

中的序列号中找到详细信息。

对于Denali以外的其他版本,您可以使用Sequence Tables。下面是一个SQL Server序列表的例子为了从序列表中读取序列号,您应该从这个启用了自动标识的sql表

中插入虚拟记录。

从SQL Server 2022开始,有一个新的操作符来解决这个问题:

GENERATE_SERIES ( start, stop [, step ] )

详细信息请参见:https://learn.microsoft.com/en-us/sql/t-sql/functions/generate-series-transact-sql?view=sql-server-ver16

相关内容

  • 没有找到相关文章

最新更新