【问题标题】:Error using Common Table Expression in SQL User Defined Function在 SQL 用户定义函数中使用公用表表达式时出错
【发布时间】:2013-10-07 21:11:29
【问题描述】:
CREATE FUNCTION [dbo].[udfGetNextEntityID]
()
RETURNS INT
AS
BEGIN
    ;WITH allIDs AS
    (
    SELECT entity_id FROM Entity 
    UNION SELECT entity_id FROM Reserved_Entity
    )       
  RETURN (SELECT (MAX(entity_id) FROM allIDs )

END
GO

SQL 不是我的强项,但我无法弄清楚我在这里做错了什么。我希望该函数从 2 个表的联合中返回最大的 entity_id。运行脚本会报错:

 Incorrect syntax near the keyword 'RETURN'.

我查看了在函数中使用 CTE 是否有一些限制,但找不到任何相关内容。我该如何纠正这个问题?

【问题讨论】:

    标签: sql sql-server sql-function


    【解决方案1】:
    CREATE FUNCTION [dbo].[udfGetNextEntityID]()
    RETURNS INT
    AS
    BEGIN
      DECLARE @result INT;
    
      WITH allIDs AS
      (
        SELECT entity_id FROM Entity 
        UNION SELECT entity_id FROM Reserved_Entity
      )       
      SELECT @result = MAX(entity_id) FROM allIDs;
    
      RETURN @result;
    
    END
    GO
    

    【讨论】:

      【解决方案2】:

      你不能从函数中返回你正在做的事情。

      利用局部变量并返回相同的变量。

       CREATE FUNCTION [dbo].[udfGetNextEntityID]()
          RETURNS INT
          AS
          BEGIN
            DECLARE @MaxEntityId INT;
      
            WITH allIDs AS
            (
              SELECT entity_id FROM Entity 
              UNION SELECT entity_id FROM Reserved_Entity
            )       
            SELECT @MaxEntityId = MAX(entity_id) FROM allIDs;
      
            RETURN @MaxEntityId ;
      
          END
       GO
      

      【讨论】:

      【解决方案3】:

      虽然你可以做到,但你为什么需要 CTE?

        RETURN
        (
          SELECT MAX(entity_id) FROM
          (
            SELECT entity_id FROM dbo.Entity 
            UNION ALL
            SELECT entity_id FROM dbo.Reserved_Entity
          ) AS allIDs
        );
      

      也没有理由使用UNION 代替UNION ALL,因为这几乎总是会引入昂贵的不同排序操作。还有please always use the schema prefix when creating / referencing any object

      【讨论】:

      • +1 同意。此外,对于 Union Vs Union All - 在这种情况下,您需要 Max 值并且不在乎行是否不同。所以,不要使用 UNION ,它会给出不同的行但会影响性能。请改用 Union All。 blog.sqlauthority.com/2009/03/11/…
      • 谢谢@Ashish,但这不是我所说的吗? :-)
      • 当然@Aaron。因为问这个问题的人说“SQL 不是我的强项”。所以,我想用 UNION Vs UNION ALL 的链接来补充你的答案,以供他参考。就是这样。
      【解决方案4】:
      create function tvfFormatstring (@string varchar(100))
      returns @fn_table table
      (id int identity(1,1),
      item int)
      as
      begin
      
      insert into @fn_table(item)
      declare @result int 
      set @string = @string+'-'
      ;with cte (start,number)
      as
      (
      
      select 1 as start , CHARINDEX('-',@string,1) as number
      union all
      select number+1 as start , CHARINDEX('-',@string,number+1) as number from cte 
      where number <= LEN(@string)
      
      )
      
      select @result = SUBSTRING(@string,start,number-start) from cte ;
      return @result;
      
      end
      
      
      
      select * from tvfFormatstring ('12321-13542-15634')
      

      【讨论】:

      • 只提供代码不是正确答案。请详细说明。
      猜你喜欢
      • 2018-07-11
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多