Sql-Server

使用者定義函式中的 PWDENCRYPT

  • January 9, 2018

在編寫隨機數函式時,我了解到您不能使用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

引用自:https://dba.stackexchange.com/questions/164367