【发布时间】:2011-04-01 16:20:03
【问题描述】:
经过一番搜索和阅读文档后,很明显您可以在 SQL Server 中编写用户定义的函数,这些函数根据主体中使用的内置函数标记为确定性或非确定性。
RAND() 列在非确定性函数下(请参阅msdn article)。那么为什么我不能在函数中使用它呢?
【问题讨论】:
标签: sql function non-deterministic
经过一番搜索和阅读文档后,很明显您可以在 SQL Server 中编写用户定义的函数,这些函数根据主体中使用的内置函数标记为确定性或非确定性。
RAND() 列在非确定性函数下(请参阅msdn article)。那么为什么我不能在函数中使用它呢?
【问题讨论】:
标签: sql function non-deterministic
使用视图可能对您有用。
来自Returning Random Numbers from a select statement
CREATE VIEW vRandNumber
AS
SELECT RAND() as RandNumber
视图是必要的,因为正如您已经发现的那样,UDF 不能使用 rand() 函数,因为这会使函数不确定。您可以使用视图来欺骗 UDF 接受随机数。
CREATE FUNCTION RandNumber()
RETURNS float
AS
BEGIN
RETURN (SELECT RandNumber FROM vRandNumber)
END
最后,您可以在任何 SELECT 中使用此函数,现在每行返回一个介于 0 和 1 之间的随机数:
SELECT dbo.RandNumber(), *
FROM Northwind..Customers
【讨论】:
getdate()。显然,该函数不能用于需要确定性函数的地方,例如持久计算列。这是因为副作用。引发的错误是“在函数中无效使用副作用运算符 'rand'。”
因为它有副作用。
函数中不允许有副作用的构造。它的副作用是更改一些内部状态,以跟踪最后发布的rand() 值。
我认为您可以通过将其包含在视图定义中然后从视图中进行选择来解决它。
【讨论】:
我发现这个solution 没有创建视图:
基本上:
代替
SET @R = Rand()
使用
SET @R = ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0
就我而言,我想要一个介于 1 和 10 之间的数字:
ROUND(((10 - 1 -1) * ( ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) + 1), 0))
ROUND(((@max - @lower -1) * ( ABS(CHECKSUM(PWDENCRYPT(N''))) / 2147483647.0) + @lower), 0))
如需完整说明:Using (Or Simulating) Rand() In A T-Sql User-Defined Function
【讨论】: