【问题标题】:Using IF BEGIN END with CTE: Incorrect syntax near the keyword `End`将 IF BEGIN END 与 CTE 一起使用:关键字“End”附近的语法不正确
【发布时间】:2016-05-08 01:01:55
【问题描述】:

发帖前查了几个问题,还是不能确定下面代码的语法有什么问题?我收到两个END 的相同错误。谢谢!

IF @UserId =''
BEGIN
  ;WITH cte AS (
   SELECT * FROM (
        SELECT  [EntryId],              
                CAST(ROW_NUMBER() OVER (ORDER BY Date DESC) AS INT) AS RN_PARENT,
                0 AS RN_CHILD
        FROM    Entries
        WHERE   [EntryDepthness] = 0 AND DiscussionWallId = @DiscussionWallId 

    ) AS Main

        WHERE ((RN_PARENT BETWEEN(@PageIndex -1) * (@PageSize) + 1   AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1))
        UNION ALL
        SELECT  e.[EntryId],            
                0 AS RN_PARENT,
                CAST(ROW_NUMBER() OVER (ORDER BY e.Date DESC) AS INT) AS RN_CHILD      
        FROM    Entries e
                INNER JOIN cte v ON v.EntryId = e.ParentEntryId 
                WHERE e.EntryDepthness = 1
    )
END
ELSE
BEGIN
  ;WITH cte AS (
   SELECT * FROM (
        SELECT  [EntryId],              
                CAST(ROW_NUMBER() OVER (ORDER BY Date DESC) AS INT) AS RN_PARENT,
                0 AS RN_CHILD
        FROM    Entries
        WHERE   [EntryDepthness] = 0 AND DiscussionWallId = @DiscussionWallId AND 
                UserId IN (
                        SELECT UserId FROM GroupStudentAssignments 
                        WHERE MemberId=@UserId AND GroupId IN (SELECT GroupId FROM GroupDiscussionRegistrations WHERE DiscussionWallId=@DiscussionWallId)
                )
    ) AS Main

    WHERE ((RN_PARENT BETWEEN(@PageIndex -1) * (@PageSize) + 1   AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1))
    UNION ALL
    SELECT  e.[EntryId],            
            0 AS RN_PARENT,
            CAST(ROW_NUMBER() OVER (ORDER BY e.Date DESC) AS INT) AS RN_CHILD      
    FROM    Entries e
            INNER JOIN cte v ON v.EntryId = e.ParentEntryId 
            WHERE e.EntryDepthness = 1
)
END

【问题讨论】:

  • 在每个 CTE 之后添加查询的其余部分...

标签: sql sql-server tsql common-table-expression


【解决方案1】:

一个CTE的语法如下

WITH CTE  (Col1, col2, col3,...)  --<-- Column names optional 
AS
 (

   -- CTE's Definition
 )
Select/Delete/Update 
FROM CTE

一旦您的 cte 定义完成,您必须从 cte 中选择/删除/更新,否则它不是有效的语法。

在您的查询中,您在定义 CTE 之前一切正常,但随后没有对它们做任何事情......

有点像.....

IF @UserId =''
BEGIN
  ;WITH cte AS (
   SELECT * FROM (
        SELECT  [EntryId],              
                CAST(ROW_NUMBER() OVER (ORDER BY Date DESC) AS INT) AS RN_PARENT,
                0 AS RN_CHILD
        FROM    Entries
        WHERE   [EntryDepthness] = 0 AND DiscussionWallId = @DiscussionWallId 

    ) AS Main

        WHERE ((RN_PARENT BETWEEN(@PageIndex -1) * (@PageSize) + 1  
             AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1))
        UNION ALL
        SELECT  e.[EntryId],            
                0 AS RN_PARENT,
                CAST(ROW_NUMBER() OVER (ORDER BY e.Date DESC) AS INT) AS RN_CHILD      
        FROM    Entries e
                INNER JOIN cte v ON v.EntryId = e.ParentEntryId 
                WHERE e.EntryDepthness = 1
    )
    select * from cte   --<-- maybe a select statment here 

END
ELSE
BEGIN
  ;WITH cte AS (
   SELECT * FROM (
        SELECT  [EntryId],              
                CAST(ROW_NUMBER() OVER (ORDER BY Date DESC) AS INT) AS RN_PARENT,
                0 AS RN_CHILD
        FROM    Entries
        WHERE   [EntryDepthness] = 0 AND DiscussionWallId = @DiscussionWallId AND 
                UserId IN (
                        SELECT UserId FROM GroupStudentAssignments 
                        WHERE MemberId=@UserId 
                        AND GroupId IN (SELECT GroupId 
                                        FROM GroupDiscussionRegistrations 
                                        WHERE DiscussionWallId=@DiscussionWallId)
                )
    ) AS Main

    WHERE ((RN_PARENT BETWEEN(@PageIndex -1) * (@PageSize) + 1   
             AND (((@PageIndex -1) * @PageSize + 1) + @PageSize) - 1))
    UNION ALL
    SELECT  e.[EntryId],            
            0 AS RN_PARENT,
            CAST(ROW_NUMBER() OVER (ORDER BY e.Date DESC) AS INT) AS RN_CHILD      
    FROM    Entries e
            INNER JOIN cte v ON v.EntryId = e.ParentEntryId 
            WHERE e.EntryDepthness = 1
)
select * from cte    --<-- and maybe a select statment here 
END

【讨论】:

    【解决方案2】:

    您不需要 IF/ELSE 块来执行此操作。

    您只需要另一个OR 条件来检查@UserId =''。试试这个方法。

    ;WITH cte 
         AS (SELECT * 
             FROM   (SELECT [entryid], 
                            Row_number() OVER (ORDER BY date DESC) AS RN_PARENT, 
                            0 AS RN_CHILD 
                     FROM   entries 
                     WHERE  [entrydepthness] = 0 
                            AND discussionwallid = @DiscussionWallId 
                            AND ( userid IN (SELECT userid 
                                             FROM   groupstudentassignments 
                                             WHERE  memberid = @UserId 
                                                    AND groupid IN (SELECT groupid FROM groupdiscussionregistrations 
                                                                    WHERE discussionwallid = @DiscussionWallId) 
                                                ) OR @UserId = '' )) AS Main --Here
             WHERE (( rn_parent BETWEEN( @PageIndex - 1 ) * ( @PageSize ) + 1 
             AND ( ( ( @PageIndex - 1 ) * @PageSize + 1 ) + @PageSize ) - 1 )) 
             UNION ALL 
             SELECT e.[entryid], 
                    0                                      AS RN_PARENT, 
                    Row_number() OVER (ORDER BY e.date DESC)  AS RN_CHILD 
             FROM   entries e 
                    INNER JOIN cte v 
                            ON v.entryid = e.parententryid 
             WHERE  e.entrydepthness = 1) 
    SELECT * 
    FROM   cte 
    

    同时删除ROW_NUMBERCast 根本不需要的ROW_NUMBER 不会生成decimal 值。

    您当前的IF/ELSE 块可能会导致参数嗅探

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-07
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多