SQL Server Msg 102, Level 15, State 1, Line 4 Incorrect syntax near '4'

v1l68za4  于 2022-12-10  发布在  其他
关注(0)|答案(1)|浏览(147)
declare @table_name varchar(50) = '' ;

select 
    @table_name = iif((@YEAR is null) AND (@WEEK is null), 'table1', 'table2')

declare @cmmnd varchar(max) = '' ;

set @cmmnd = 'SELECT B.* 
              INTO #temptable
              FROM [schema1].' + @table_name + ' B WITH (READUNCOMMITTED)
              WHERE B.Start <= CAST(' + CAST(@DATE AS varchar(30)) + ' AS DATETIME)
                AND ISNULL(B.End, IIF(B.CrntR = 1, CAST(' + CAST(@DATE AS varchar(30)) + ' AS DATETIME) + 1, CAST('
                + CAST(@DATE AS varchar(30)) + ' AS DATETIME) - 1)) > CAST('  + CAST(@DATE AS varchar(30)) + ' AS DATETIME)';

EXEC (@cmmnd);

Why I am getting this error?
Msg 102, Level 15, State 1, Line 4
Incorrect syntax near '4'
I am using SQL Server 2014 version
I tried changing the code, but still get the same error.

cyvaqqii

cyvaqqii1#

You debug dynamic SQL using the PRINT statement to print the SQL you are about to run - then you can debug it as static SQL. Printing your statement gives:

SELECT B.* 
INTO #temptable
FROM [schema1].table1 B WITH (READUNCOMMITTED)
WHERE B.Start <= CAST(2022-12-10 AS DATETIME)
AND ISNULL(B.End, IIF(B.CrntR = 1, CAST(2022-12-10 AS DATETIME) + 1, CAST(2022-12-10 AS DATETIME) - 1)) > CAST(2022-12-10 AS DATETIME)

Which if you paste into SSMS shows you a lot of syntax errors.

  1. You aren't quoting your date strings
  2. You aren't escaping the keywords you are using as column names e.g. Start and End The correct query is:
set @cmmnd = 'SELECT B.* 
INTO #temptable
FROM [schema1].' + @table_name + ' B WITH (READUNCOMMITTED)
WHERE B.[Start] <= CAST(''' + CAST(@DATE AS varchar(30)) + ''' AS datetime)
AND ISNULL(B.[End], DATEADD(day, IIF(B.CrntR = 1, 1, -1), CAST(''' + CAST(@DATE AS varchar(30)) + ''' AS datetime))) > CAST(''' + CAST(@DATE AS varchar(30)) + ''' AS datetime)';

Which fixes those 2 issues and simplifies the logic in your IIF statement, while using the correct datetime function to add days rather than depending on knowing that +/-1 refers to days. This returns:

SELECT B.* 
INTO #temptable
FROM [schema1].table1 B WITH (READUNCOMMITTED)
WHERE B.[Start] <= CAST('2022-12-10' AS datetime)
AND ISNULL(B.[End], DATEADD(day, IIF(B.CrntR = 1, 1, -1), CAST('2022-12-10' AS datetime))) > CAST('2022-12-10' AS datetime)

Which parses at least - but I can't test it further than that.
Note: I'm not convinced your logic makes sense, for a certain input ( B.CrntR <> 1 ) you are checking whether a constant date of '2022-12-10', minus a day, is greater then itself - but if thats an issue it needs another question.

相关问题