关键字'with'附近的语法不正确。

时间:2011-08-11 20:30:58

标签: sql sql-server sql-server-2008

您好我想弄清楚为什么在MYSQL中将我的兼容模式从80切换到100会破坏我的功能?

    Microsoft SQL Server 2008 R2 (RTM) - 10.50.1617.0 (X64)   Apr 22 2011 19:23:43
Copyright (c) Microsoft Corporation  Express Edition with Advanced Services (64-bit) on
Windows NT 6.1 <X64> (Build 7601: Service Pack 1)

这是我的功能:

GO
ALTER FUNCTION [dbo].[GetRoot] 
(
    @Param1 int 
)
RETURNS varchar(50)
AS
BEGIN
DECLARE @ReturnValue varchar(50)
with results as
    (
        select parentouid,net_ouid from net_ou where net_ouid=@Param1
        union all
        select t2.parentouid,t2.net_ouid from net_ou t2 
        inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
    )   
    select @ReturnValue = net_ou.displayname 
    from  NET_OU RIGHT OUTER JOIN
    results ON net_ou.net_ouid = results.ParentouID where results.parentouid=results.net_ouid

    RETURN @ReturnValue

END

3 个答案:

答案 0 :(得分:36)

尝试在with:

前面抛出一个半冒号
;with results as
    (
        select parentouid,net_ouid from net_ou where net_ouid=@Param1
        union all
        select t2.parentouid,t2.net_ouid from net_ou t2 
        inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
    )   

this article一个阅读,以了解您为什么需要这样做。 Snipit:

  

但是,如果CTE不是批次中的第一个语句,则必须   在WITH关键字前面加一个分号。作为最佳实践,我   我希望用分号为我的所有CTE添加前缀 - 我发现这个   一致的方法比记住我是否需要一个更容易   分号与否。

就我个人而言,我不会为每个 CTE做这件事,但如果这样做会让事情变得更容易,那么就不会有任何伤害。

答案 1 :(得分:5)

WITH之前添加分号:

;with results as
    (
        select parentouid,net_ouid from net_ou where net_ouid=@Param1
        union all
        select t2.parentouid,t2.net_ouid from net_ou t2 
        inner join results t1 on t1.parentouid = t2.net_ouid where t2.parentouid <> t1.net_ouid
    )   
    select @ReturnValue = net_ou.displayname 
    from  NET_OU RIGHT OUTER JOIN
    results ON net_ou.net_ouid = results.ParentouID where results.parentouid=results.net_ouid

    RETURN @ReturnValue

END

CTE声明需要是批处理中的第一个命令。

答案 2 :(得分:0)

我建议您采用以分号结束所有语句的做法。这是ANSI标准的一部分,可以在需要处理其他数据库时为您提供帮助。无论如何,SQL Server正朝着这个方向发展。现在SQL Server 2012中有更多命令需要分号。

E.g。

ALTER FUNCTION [dbo].[GetRoot] 
    (@Param1 int)
RETURNS varchar(50)
AS
BEGIN
    DECLARE @ReturnValue VARCHAR(50)
    ;
    WITH cteResults 
    AS (SELECT parentouid
              ,net_ouid 
          FROM net_ou 
         WHERE net_ouid=@Param1
         UNION ALL
        SELECT t2.parentouid,t2.net_ouid 
          FROM net_ou t2 
         INNER JOIN results t1 
                 ON t1.parentouid = t2.net_ouid
         WHERE t2.parentouid <> t1.net_ouid )   
    SELECT @ReturnValue = net_ou.displayname 
      FROM net_ou 
     RIGHT JOIN cteResults 
             ON net_ou.net_ouid = results.ParentouID
     WHERE results.parentouid=results.net_ouid
    ;   
    RETURN @ReturnValue
    ;   
END
;
GO

作为一个额外的奖励,它使您查询废话负载更容易阅读。 ; - )