【发布时间】:2016-08-03 23:28:20
【问题描述】:
我正在尝试定义这个函数:
CREATE FUNCTION getRandomName ()
RETURNS VARCHAR(48)
AS BEGIN
-- concatenate two random strings from two columns in a table and return as a new string
DECLARE @finalStr VARCHAR(48);
SET @finalStr = (SELECT TOP 1 st1 FROM randomStrings ORDER BY RAND()) +
' ' +
(SELECT TOP 1 st2 FROM randomStrings ORDER BY RAND());
RETURN @finalStr;
END
我不能这样做,因为:
Msg 443, Level 16, State 1, Procedure getRandomName, Line 6
Invalid use of a side-effecting operator 'rand' within a function.
我在网上找到的与此问题相关的帖子建议在调用函数时传入随机值作为参数,或者使用视图并在函数中查询该视图以将单个随机数放入变量中。我不能使用这些方法,因为我试图在 ORDER BY 子句中使用随机化。
有没有办法做到这一点?
(SQL Server 2014)
编辑:
因此您可以使用视图来获得如下所述的结果,但现在我发现自己需要将参数传递给函数:
CREATE FUNCTION getRandomName (
@maxPieceSize int
)
RETURNS VARCHAR(48)
AS BEGIN
-- concatenate two random strings from two columns in a table and return as a new string
DECLARE @finalStr VARCHAR(48);
SET @finalStr = (SELECT TOP 1 st1 FROM randomStrings WHERE LEN(st1) <= @maxPieceSize ORDER BY RAND()) +
' ' +
(SELECT TOP 1 st2 FROM randomStrings WHERE LEN(st1) <= @maxPieceSize ORDER BY RAND());
RETURN @finalStr;
END
所以我不能为这个场景创建一个视图,因为你不能将参数传递给视图。
所以这是我的困境:
- 函数:我不能使用它,因为我不能在函数中使用任何非确定性函数。
- 查看:我不能使用这个,因为我需要向“函数”传递一个参数。
- 过程:我能看到的唯一方法是使用输出变量,这意味着声明一个变量等。我不能简单地执行
EXECUTE getRandomName(6)或SELECT getRandomName(6)之类的操作。
我是否坚持使用过程并以“艰难的方式”执行它(使用输出变量,并且每次我想使用该方法时都必须声明该变量)?
再次编辑:
我尝试将实际方法编写为存储过程,然后从声明变量的函数调用该存储过程,分配它然后返回它。这是有道理的。除了……
Msg 557, Level 16, State 2, Line 1
Only functions and some extended stored procedures can be executed from within a function.
我猜 SQL Server 真的不希望我有一个可以返回随机值的函数。 (有趣的是,RAND() 本身不是一个函数吗?)
【问题讨论】:
-
如果你想要类似的东西,你可以通过
newid()而不是rand来订购 -
Msg 443,级别 16,状态 1,过程 getRandomName,第 6 行 在函数中无效使用副作用运算符“newid”。
-
FWIW: stackoverflow.com/questions/3531450/… 有额外的解释和“技巧”。
-
确实如此。正如答案所解释的,您不能在标准函数中使用随机性,但可以有随机参数。例如
create function myFunction ( @input1 varchar(255), @input2 varchar(255) ) returns varchar(255) as begin return @input1 + ' ' + @input2; end并调用select dbo.myFunction((select top 1 st1 from randomstrings order by newid()), (select top 1 st1 from randomstrings order by newid()));之类的函数 -
想象一下,您设法编写了满足您需求的函数。请告诉我们您打算如何使用它。很可能在没有该函数的情况下可以重写查询。 (功能代码可以在主查询中“内联”)。这将消除对技巧的需求并提高整体查询效率。
标签: sql-server tsql sql-server-2014