CTE后语法不正确

时间:2013-01-28 11:32:28

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

declare @SQL nvarchar(max);
with tbl1 as
    (
    SELECT ...
    ),
tbl2 as
    (
    SELECT ...
    ),
tbl15 as
    (
    select [tbl1].[DT],
    [tbl1].[Kr_IL.BTS],
    [tbl2].[Kr_IL.CS],
    from [tbl1], [tbl2]
    where 
    [tbl1].[DT] = [tbl2].[DT] 
    and [tbl1].[DT] = [tbl3].[DT] 
    )

set @SQL = 'select [tbl15].[DT], '
if @tag1 = 1 set @SQL = @SQL + '[tbl15].[Kr_IL.BTS], '
    else set @SQL = @SQL + 'null as [Kr_IL.BTS], '
if @tag2 = 1 set @SQL = @SQL + '[tbl15].[Kr_IL.CS], '
    else set @SQL = @SQL + 'null as [Kr_IL.CS], ';
set @SQL = STUFF(@SQL, len(@SQL), 1, ' from [tbl15]')
exec (@SQL)

这是我遇到问题的存储过程脚本的一部分。消息是:

  

“消息156,级别15,状态1,过程SP_select,行202不正确   关键字'set'附近的语法。“。

如果我写一个标准的select语句(带有完整的列集),它可以正常工作。但我需要“控制”列(真实数据或根据启用标记的空数据)。 根据错误消息,错误点是:

set @SQL = 'select [tbl15].[DT], '

提前致谢。

1 个答案:

答案 0 :(得分:11)

您收到此错误是因为您没有立即在查询中引用CTE(动态SQL不计算!)

通过使用case语句,可以直接将用于控制流的变量引入脚本,而不是需要动态SQL:

SELECT [DT],
       CASE
         WHEN @tag1 = 1 THEN [Kr_IL.BTS]
         ELSE NULL
       END AS BTS,
       CASE
         WHEN @tag2 = 1 THEN [Kr_IL.CS]
         ELSE NULL
       END AS CS
FROM   tbl15

所以你的整个剧本变成了:

;WITH tbl1 AS
    (
    SELECT ...
    ),
tbl2 AS
    (
    SELECT ...
    ),
tbl15 AS
    (
    SELECT [tbl1].[DT],
    [tbl1].[Kr_IL.BTS],
    [tbl2].[Kr_IL.CS],
    FROM [tbl1], [tbl2]
    WHERE
    [tbl1].[DT] = [tbl2].[DT]
    AND [tbl1].[DT] = [tbl3].[DT]
    )
SELECT [DT],
       CASE
         WHEN @tag1 = 1 THEN [Kr_IL.BTS]
         ELSE NULL
       END AS BTS,
       CASE
         WHEN @tag2 = 1 THEN [Kr_IL.CS]
         ELSE NULL
       END AS CS
FROM   tbl15