Sql-Server
使用者定義函式中的 PWDENCRYPT
在編寫隨機數函式時,我了解到您不能使用
NEWID()
或RAND()
在使用者函式內部,因為它們是非確定性的。我還發現我可以使用
PWDENCRYPT
它並擺脫它。我會認為這也是非確定性的。它確實為我提供了一個足夠隨機的值用於測試目的(我不是想在這裡模擬量子物理學)。我的問題:
- 在使用者函式中
PWDENCRYPT
真的可以接受(即,它現在可以工作,但我可以期望它繼續工作)嗎?- 它是否足夠隨機(對於隨機的合理定義)?
PWDENCRYPT
有點過時了,所以不,你現在不應該使用它,你當然不應該期望它以任何方式無限期地工作- 確定性與否。從文件中:PWDENCRYPT 是一個較舊的函式,可能在 SQL Server 的未來版本中不受支持。請改用HASHBYTES。HASHBYTES 提供了更多的雜湊算法。
我不知道有人能回答你的第二個問題。你如何定義“足夠隨機”?
另外,為了清楚起見,
NEWID()
並且RAND()
在函式中被禁止不是因為它們是不確定的,而是因為它們被認為是“副作用”——即使你或我無法假設這些函式如何影響任何東西,除了增加一些內部隨機數序列生成器。無論如何,有一些簡單的解決方法 - 例如創建一個視圖並讓函式引用視圖,傳遞
NEWID()
給函式等。除了
PWDENCRYPT()
,其他顯然也不是確定性的函式(例如GETDATE()
、SYSUTCDATETIME()
、CURRENT_TIMESTAMP
等)也是允許的。例子:CREATE OR ALTER FUNCTION dbo.what() RETURNS int AS BEGIN RETURN (SELECT @@DBTS + @@CPU_BUSY + @@CONNECTIONS + DATEDIFF(SECOND, GETDATE(), SYSUTCDATETIME())); END GO SELECT dbo.what();
該函式將被標記為非確定性(您可以使用 確認
OBJECTPROPERTY()
),這可以限制 UDF 的使用方式,但並非“使用者定義的函式中不允許使用非確定性函式。 " 儘管這是很多人寫的,但嚴格來說並非如此。事實上,當提供種子時,
RAND()
被證明是確定性的;RAND(5);
顯然是確定性的。但它仍然不允許在函式中使用(這會返回相同的副作用錯誤):CREATE FUNCTION dbo.who() RETURNS decimal(20,19) AS BEGIN RETURN (SELECT RAND(5)); END GO