0

我在函数中使用 NEWID() 。这是我的功能:

CREATE FUNCTION dbo.myFunc (@newid NVARCHAR(50))
RETURNS int

AS BEGIN
    declare @rndValue int
    set @rndValue = (SELECT top 1 * FROM #temp ORDER BY lower(@newid))
    RETURN @rndValue 
END

我有 #temp 的值:'1','2','3' 我想使用这个函数从这个表中随机抽取。我这样称呼这个函数:

dbo.myFunc (NEWID())

但我每次都得到相同的值('1')

我的错误在哪里?

4

3 回答 3

3

该函数使用NEWID()。它使用名为的字符串参数的值@newid

如果要选择随机行,请使用ORDER BY NEWID(). 这会为每一行生成一个新的非顺序 GUID 并按它对行进行排序,从而有效地产生随机排序,例如:

set @rndValue = (SELECT top 1 * FROM #temp ORDER BY newid())

原始查询按常量对行进行排序,因此没有效果。这与使用没有什么不同

set @rndValue = (SELECT top 1 * FROM #temp ORDER BY 'potato')

如果您检查查询的执行计划,您会发现没有 SORT 操作。查询优化器只是删除无效的ORDER BY子句。

最后,NEWID()产生一个GUID,而不是一个字符串。这是一个 128 位的二进制值。使用LOWER()没有任何目的

于 2020-02-05T08:09:58.040 回答
2

你在做什么看起来很奇怪,但如果你需要这种格式,请使用下面的代码:

CREATE VIEW dbo.GetGUID
AS
SELECT NEWID() AS [NewID]

GO


CREATE TABLE dbo.temp
(
    id int
);

GO

INSERT INTO dbo.temp
VALUES (1), (2), (3);


GO

CREATE FUNCTION dbo.myFunc ()
RETURNS int

AS BEGIN
    declare @rndValue int
    set @rndValue = (SELECT top 1 id FROM dbo.temp CROSS APPLY  dbo.GetGUID ORDER BY [NewID])
    RETURN @rndValue 
END

GO

SELECT  dbo.myFunc()
SELECT  dbo.myFunc()
SELECT  dbo.myFunc()
SELECT  dbo.myFunc()
SELECT  dbo.myFunc()
SELECT  dbo.myFunc()

在此处输入图像描述

基本上,如果您需要 NEWID() 功能,则需要使用 view hack

于 2020-02-05T08:37:52.170 回答
-1
CREATE FUNCTION dbo.myFunc (@newid NVARCHAR(50))
RETURNS int

AS BEGIN
    declare @rndValue int
    set @rndValue = (SELECT top 1 * FROM #temp ORDER BY @newid)
    RETURN @rndValue 
END
于 2020-02-05T08:38:59.230 回答