используя NEWID () внутри функции - как переменную - но каждый раз получая одно и то же значение - PullRequest
0 голосов
/ 05 февраля 2020

Я использую 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')

где моя ошибка?

Ответы [ 3 ]

3 голосов
/ 05 февраля 2020

Функция не с использованием 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() не имеет смысла

2 голосов
/ 05 февраля 2020

То, что вы делаете, выглядит странно, но если вам нужно в этом формате, используйте код ниже:

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()

enter image description here

В основном, если вам нужно иметь функцию NEWID (), вам нужно использовать представление hack.

0 голосов
/ 05 февраля 2020
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
...