使用IF BEGIN END和CTE:关键字“End”附近的语法不正确

时间:2016-05-08 01:01:55

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

我在发布之前已经检查了几个问题,但仍然无法确定以下代码的语法有什么问题?我收到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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您不需要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 

同时删除Cast ROW_NUMBER完全不需要的ROW_NUMBER decimal不生成IF/ELSE值。

您当前的{{1}}阻止可能导致参数嗅探