在 UDF 中选择随机记录

selecting random records inside a UDF

我正在 sql 服务器 2012 中编写函数。 我开始知道我们不能在 sql 服务器中的函数的 select 语句中使用 RAND()NEWID() 函数。 我的功能是这样的:

CREATE FUNCTION Keywordsuggester (@userid INT) 
returns @suggestor_tab TABLE ( 
  keywordid       INT, 
  keywordname     VARCHAR(max), 
  keywordcategory VARCHAR(max)) 
AS 
  BEGIN 
      DECLARE @category_table TABLE 
        ( 
           category_name VARCHAR(max), 
           category_id   INT, 
           rownum        INT 
        ) 
      DECLARE @ID INT = 1 
      DECLARE @COUNT INT = 0 
      DECLARE @I INT = 1 

      INSERT INTO @category_table 
      SELECT kc.NAME, 
             kc.id, 
             k.NAME, 
             d.NAME, 
             Row_number() 
               OVER( 
                 ORDER BY d.id ASC) AS rownum 
      FROM   dtypes d 
             JOIN keywords k 
               ON d.NAME LIKE '%' + k.NAME + '%' 
             JOIN keywordscategory kc 
               ON k.categoryid = kc.id 
      WHERE  d.userid = @userid 

      SELECT @count = rownum 
      FROM   @category_table 

      WHILE @count > @I 
        BEGIN 
            INSERT INTO @suggestor_tab 
            SELECT TOP 5 kc.id, 
                         k.NAME, 
                         kc.NAME 
            FROM   kwords k 
                   JOIN @category_table ct 
                     ON k.categoryid = ct.category_id 
                   JOIN kwcategory kc 
                     ON kc.NAME = ct.category_name 
            WHERE  ct.rownum = @I 

            --Here I'm inserting top 5 records for each category into the suggestor_tab,instead I have to insert random 5 records for each category(i.e.,@I)
            SET @I=@I + 1 
        --return 
        END 

      INSERT INTO @suggestor_tab 
      SELECT kc.id, 
             k.NAME, 
             kc.NAME 
      FROM   kwords k 
             JOIN @category_table ct 
               ON k.categoryid = ct.category_id 
             JOIN kwcategory kc 
               ON kc.NAME = category_name 

      RETURN 
  END 

如何获取每个类别的随机记录(即 while 循环中的@I)。 我尝试了这样的查询:

    SELECT TOP 5 k.NAME 
FROM   kwords k 
       JOIN @category_table ct 
         ON k.category_id = ct.id 
       JOIN kwcategory kc 
         ON kc.NAME = category_name 
WHERE  ct.rownum = @I 
ORDER  BY Newid() 

抛出如下错误:

Invalid use of a side-effecting operator 'newid' within a function.

有办法吗? 提前致谢。

您不能在 UDF 中使用 Non-deterministic 函数。

创建一个 View 并在 order by

中使用它
create view Random 
as
select newid() as New_id

改变你select这样的东西。

SELECT TOP 5 k.NAME
FROM   KWords k
        JOIN @category_table ct
            ON k.category_id = ct.id
        JOIN kwcategory kc
            ON kc.NAME = category_name
WHERE  ct.rownum = @I
ORDER  BY (SELECT new_id
            FROM   random)