Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Incorrect syntax after CTE

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)

This is part of stored procedure script I have a problem with. The message is:

"Msg 156, Level 15, State 1, Procedure SP_select, Line 202 Incorrect syntax near the keyword 'set'.".

If I write a standard select statement (with full set of columns) it works fine. But I need to "control" the columns (real data or null data according enable tags). According error message the error point is:

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

Thanks in advance.

like image 287
Paulius_B Avatar asked Jan 28 '13 11:01

Paulius_B


People also ask

How can I use if statement after a CTE?

WITH declares a CTE, which is something you can use in just 1 statement (like a SELECT , INSERT , UPDATE , etc.). An IF is a control flow mechanic that separates statements (or blocks of statements) so you can't declare a CTE and conditionally refer to it on multiple statements.

What is CTE syntax?

CTE was introduced in SQL Server 2005, the common table expression (CTE) is a temporary named result set that you can reference within a SELECT, INSERT, UPDATE, or DELETE statement. You can also use a CTE in a CREATE a view, as part of the view's SELECT query.

What is required in CTE syntax?

The CTE syntax includes a CTE name, an optional column list, and a statement/query that defines the common table expression (CTE). After defining the CTE, we can use it as a view in a SELECT, INSERT, UPDATE, DELETE, and MERGE query. The following is the basic syntax of CTE in SQL Server: WITH cte_name (column_names)

Which clause Cannot be used in CTE?

The clauses like ORDER BY, INTO, OPTION clause with query hints, FOR XML, FOR BROWSE, cannot be used in the CTE query definition. "SELECT DISTINCT", GROUP BY, PIVOT, HAVING, Scalar aggregation, TOP, LEFT, RIGHT, OUTER JOIN, and Subqueries are not allowed in the CTE query definition of a recursive member.


1 Answers

You're getting this error because you're not referencing the CTE in the query immediately after it (dynamic SQL doesn't count!)

Your variables for controlling the flow could be introduced into the script directly, rather than the need for dynamic SQL, by using a case statement:

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

So your whole script becomes:

;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
like image 166
Bridge Avatar answered Oct 13 '22 13:10

Bridge