【问题标题】:How to generate unique numbers inside a UDF (SQL Server)如何在 UDF 中生成唯一编号(SQL Server)
【发布时间】:2011-09-16 05:13:30
【问题描述】:

有没有办法在用户定义的函数中生成唯一数字(例如 int)?

rand() 和 newid() 由于副作用而不起作用。

谢谢。

【问题讨论】:

    标签: sql-server tsql sql-server-2008 random user-defined-functions


    【解决方案1】:

    CRYPT_GEN_RANDOM 绕过 NEWID() 限制

    SELECT CHECKSUM(CRYPT_GEN_RANDOM(8000))
    

    所以你可以像这样使用它。没有“副作用”错误

    CREATE FUNCTION dbo.test ()
    RETURNS int
    AS
    BEGIN
       RETURN CHECKSUM(CRYPT_GEN_RANDOM(8000))
    END
    GO
    SELECT dbo.test()
    

    【讨论】:

    • 感谢@gbn,这似乎有效。不过有个小问题,CHECKSUM 不能保证对不同的论点总是产生不同的结果,但我想进入这种情况的机会真的很小吗?
    • 40 亿分之一(整数范围)唯一性,以birthday problem 为准。 NEWID() 会遇到同样的问题,因为您需要从 GUID 中获取一个数字。
    • 我仍然收到内联函数的错误:Msg 443, Level 16, State 1, Procedure //InlineFunctionName//, Line //LineNum// [Batch Start Line 0] Invalid use of a函数中的副作用运算符“Crypt_Gen_Random”。
    • 我和莱利有同样的问题。用 CHECKSUM 包围函数并不能防止错误。
    【解决方案2】:

    在 DB2 中,我使用时间戳的微秒部分,但 SQL Server 只使用毫秒。我怀疑这还不够好?

    【讨论】:

    • 仅供参考,SQL Server 2008+ 使用新类型达到 100ns
    【解决方案3】:

    您还可以使用导致副作用的函数(在本例中为 RAND())定义视图

    CREATE VIEW randomView
    AS
    SELECT RAND() randomResult
    GO
    

    然后在你的 UDF 中使用视图

    DECLARE @random DECIMAL(18,18) 
    SELECT @random = randomResult FROM randomView
    RETURN @random
    

    【讨论】:

    • 这真是太棒了。它是如此简单,以至于我怀疑它是否会起作用(尤其是在多年来试图绕过微软对函数和存储过程的许多严格和人为的限制之后),但它在 SQL Server 2014 中为我做了诀窍,与标记的答案不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 2014-07-20
    • 2011-05-21
    • 2012-02-01
    • 2012-04-14
    相关资源
    最近更新 更多