SQL 字符串附近的 OpenQuery 语法不正确
SQL OpenQuery incorrect syntax near string
我正在尝试 运行 存储过程中的以下查询。当我尝试使用硬编码值而不是变量 运行 它时,它 运行 没问题。但是就在我尝试将整个查询包含在一个变量中并执行它时,它给我一个错误提示:Incorrect syntax near 'FIFO'.
我尝试用双引号替换单引号,但没有用。请帮忙!
DECLARE @TSQL nvarchar(max); Declare @STATION_CODE varchar(max); Declare @STATION_CODE_PREV varchar(max);
SET @STATION_CODE='1600020'; SET @STATION_CODE_PREV='1600007'; SET @TSQL='SELECT * FROM OPENQUERY (VFDB,''SELECT COUNT(TABLE_7.FIFO) AS FIFO_COUNT,TABLE_7.FIFO,TABLE_7.Day_Hour ,TABLE_7.Station_Code,''FIFO'' AS Element FROM ( select CAST(CASE WHEN TABLE_6 .BCD_PRV2_EXIT=TABLE_5 .BCD_PRV2 THEN ''1'' ELSE ''0'' END AS INT) FIFO, case when datepart(hour,TABLE_6.CREATION_DATE_E3 )<10
then
''0''
+Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':00 - ''+''0''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':59''
else
Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':00 - ''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':59''
end As Day_Hour ,TABLE_6.Station_Code As Station_Code from
( select T1_ENTRY.RANK1_ENTRY AS T5_R1, T1_ENTRY.BCD_PRV1,T1_ENTRY.CREATION_DATE_E1,T2_ENTRY.RANK2_ENTRY , T2_ENTRY.BCD_PRV2 ,T2_ENTRY.CREATION_DATE_E2 from
(
select MFG_UNIT_NUM as BCD_PRV1,CREATION_DATE AS CREATION_DATE_E1 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''REFRIGERATOR'', NULL, '''''+ @STATION_CODE +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T1_ENTRY LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2,CREATION_DATE AS CREATION_DATE_E2,ROW_NUMBER()over(order by Creation_Date) as RANK2_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''REFRIGERATOR'', NULL, '''''+ @STATION_CODE_PREV +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T2_ENTRY ON T1_ENTRY.RANK1_ENTRY=T2_ENTRY.RANK2_ENTRY-1
) TABLE_5
LEFT JOIN
( select T3_EXIT.RANK1_EXIT AS T6_R1, T3_EXIT.BCD_PRV1_EXIT,T3_EXIT.CREATION_DATE_E3,T4_EXIT.RANK2_EXIT , T4_EXIT.BCD_PRV2_EXIT ,T4_EXIT.CREATION_DATE_E4,T3_EXIT.Station_Code from
(
select MFG_UNIT_NUM as BCD_PRV1_EXIT,CREATION_DATE AS CREATION_DATE_E3 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''REFRIGERATOR'', NULL, '''+@STATION_CODE+''',NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T3_EXIT LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2_EXIT,CREATION_DATE AS CREATION_DATE_E4,ROW_NUMBER()over(order by Creation_Date) as RANK2_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''REFRIGERATOR'', NULL,'''+@STATION_CODE_PREV+''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T4_EXIT ON T3_EXIT.RANK1_EXIT=T4_EXIT.RANK2_EXIT-1 ) TABLE_6 ON TABLE_5.BCD_PRV2=TABLE_6.BCD_PRV2_EXIT )TABLE_7 GROUP BY TABLE_7.FIFO,TABLE_7.Day_Hour ,Table_7. STATION_CODE'')';
EXEC sp_executesql @TSQL;
假设您有一些带有字符串的动态 SQL:
'SELECT * FROM foo WHERE bar = ''i am a string'';'
-- ^^ ^^
-- || ||
-- notice the double quotes
现在让我们用 OPENQUERY
来做,在动态 SQL 中(你的情况):
'SELECT * FROM OPENQUERY (VFDB,''SELECT * FROM foo WHERE bar = ''''i am a string'''';'')'
-- ^^ ^^^^
-- || ||||
-- double quotes escaped double quotes => 4 quotes
您在字符串中嵌套了查询,因此每次添加嵌套级别时,您都必须将引号加倍以避免关闭较高的嵌套级别。
强烈反对,因为调试起来真的很痛苦,正如您猜到的那样,更不用说变量连接可能是多么混乱(但是您已经为此使用了 5 个引号,所以您已经知道了:))。
我修复引号的尝试(无法测试,所以也许我在某些时候搞砸了):
DECLARE @TSQL nvarchar(max); Declare @STATION_CODE varchar(max); Declare @STATION_CODE_PREV varchar(max);
SET @STATION_CODE='1600020'; SET @STATION_CODE_PREV='1600007'; SET @TSQL='SELECT * FROM OPENQUERY (VFDB,''''SELECT COUNT(TABLE_7.FIFO) AS FIFO_COUNT,TABLE_7.FIFO,TABLE_7.Day_Hour ,TABLE_7.Station_Code,''''FIFO'''' AS Element FROM ( select CAST(CASE WHEN TABLE_6 .BCD_PRV2_EXIT=TABLE_5 .BCD_PRV2 THEN ''''1'''' ELSE ''''0'''' END AS INT) FIFO, case when datepart(hour,TABLE_6.CREATION_DATE_E3 )<10
then
''''0''''
+Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':00 - ''''+''''0''''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':59''''
else
Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':00 - ''''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':59''''
end As Day_Hour ,TABLE_6.Station_Code As Station_Code from
( select T1_ENTRY.RANK1_ENTRY AS T5_R1, T1_ENTRY.BCD_PRV1,T1_ENTRY.CREATION_DATE_E1,T2_ENTRY.RANK2_ENTRY , T2_ENTRY.BCD_PRV2 ,T2_ENTRY.CREATION_DATE_E2 from
(
select MFG_UNIT_NUM as BCD_PRV1,CREATION_DATE AS CREATION_DATE_E1 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''''REFRIGERATOR'''', NULL, '''''+ @STATION_CODE +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T1_ENTRY LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2,CREATION_DATE AS CREATION_DATE_E2,ROW_NUMBER()over(order by Creation_Date) as RANK2_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''''REFRIGERATOR'''', NULL, '''''+ @STATION_CODE_PREV +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T2_ENTRY ON T1_ENTRY.RANK1_ENTRY=T2_ENTRY.RANK2_ENTRY-1
) TABLE_5
LEFT JOIN
( select T3_EXIT.RANK1_EXIT AS T6_R1, T3_EXIT.BCD_PRV1_EXIT,T3_EXIT.CREATION_DATE_E3,T4_EXIT.RANK2_EXIT , T4_EXIT.BCD_PRV2_EXIT ,T4_EXIT.CREATION_DATE_E4,T3_EXIT.Station_Code from
(
select MFG_UNIT_NUM as BCD_PRV1_EXIT,CREATION_DATE AS CREATION_DATE_E3 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''''REFRIGERATOR'''', NULL, '''''+@STATION_CODE+''''',NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T3_EXIT LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2_EXIT,CREATION_DATE AS CREATION_DATE_E4,ROW_NUMBER()over(order by Creation_Date) as RANK2_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''''REFRIGERATOR'''', NULL,'''''+@STATION_CODE_PREV+''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T4_EXIT ON T3_EXIT.RANK1_EXIT=T4_EXIT.RANK2_EXIT-1 ) TABLE_6 ON TABLE_5.BCD_PRV2=TABLE_6.BCD_PRV2_EXIT )TABLE_7 GROUP BY TABLE_7.FIFO,TABLE_7.Day_Hour ,Table_7. STATION_CODE'')';
EXEC sp_executesql @TSQL;
您已经得到了答案,所以这只是一个提示,您以后如何轻松解决此类问题。
declare @sql_string varchar(100)
set @sql_string = 'SELECT * FROM OPENQUERY (VFDB,''SELECT * FROM foo WHERE bar = ''''i am a string'''';'')'
select @sql_string --> This here will let you see how your string looks like
我正在尝试 运行 存储过程中的以下查询。当我尝试使用硬编码值而不是变量 运行 它时,它 运行 没问题。但是就在我尝试将整个查询包含在一个变量中并执行它时,它给我一个错误提示:Incorrect syntax near 'FIFO'.
我尝试用双引号替换单引号,但没有用。请帮忙!
DECLARE @TSQL nvarchar(max); Declare @STATION_CODE varchar(max); Declare @STATION_CODE_PREV varchar(max);
SET @STATION_CODE='1600020'; SET @STATION_CODE_PREV='1600007'; SET @TSQL='SELECT * FROM OPENQUERY (VFDB,''SELECT COUNT(TABLE_7.FIFO) AS FIFO_COUNT,TABLE_7.FIFO,TABLE_7.Day_Hour ,TABLE_7.Station_Code,''FIFO'' AS Element FROM ( select CAST(CASE WHEN TABLE_6 .BCD_PRV2_EXIT=TABLE_5 .BCD_PRV2 THEN ''1'' ELSE ''0'' END AS INT) FIFO, case when datepart(hour,TABLE_6.CREATION_DATE_E3 )<10
then
''0''
+Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':00 - ''+''0''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':59''
else
Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':00 - ''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'':59''
end As Day_Hour ,TABLE_6.Station_Code As Station_Code from
( select T1_ENTRY.RANK1_ENTRY AS T5_R1, T1_ENTRY.BCD_PRV1,T1_ENTRY.CREATION_DATE_E1,T2_ENTRY.RANK2_ENTRY , T2_ENTRY.BCD_PRV2 ,T2_ENTRY.CREATION_DATE_E2 from
(
select MFG_UNIT_NUM as BCD_PRV1,CREATION_DATE AS CREATION_DATE_E1 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''REFRIGERATOR'', NULL, '''''+ @STATION_CODE +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T1_ENTRY LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2,CREATION_DATE AS CREATION_DATE_E2,ROW_NUMBER()over(order by Creation_Date) as RANK2_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''REFRIGERATOR'', NULL, '''''+ @STATION_CODE_PREV +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T2_ENTRY ON T1_ENTRY.RANK1_ENTRY=T2_ENTRY.RANK2_ENTRY-1
) TABLE_5
LEFT JOIN
( select T3_EXIT.RANK1_EXIT AS T6_R1, T3_EXIT.BCD_PRV1_EXIT,T3_EXIT.CREATION_DATE_E3,T4_EXIT.RANK2_EXIT , T4_EXIT.BCD_PRV2_EXIT ,T4_EXIT.CREATION_DATE_E4,T3_EXIT.Station_Code from
(
select MFG_UNIT_NUM as BCD_PRV1_EXIT,CREATION_DATE AS CREATION_DATE_E3 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''REFRIGERATOR'', NULL, '''+@STATION_CODE+''',NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T3_EXIT LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2_EXIT,CREATION_DATE AS CREATION_DATE_E4,ROW_NUMBER()over(order by Creation_Date) as RANK2_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''REFRIGERATOR'', NULL,'''+@STATION_CODE_PREV+''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T4_EXIT ON T3_EXIT.RANK1_EXIT=T4_EXIT.RANK2_EXIT-1 ) TABLE_6 ON TABLE_5.BCD_PRV2=TABLE_6.BCD_PRV2_EXIT )TABLE_7 GROUP BY TABLE_7.FIFO,TABLE_7.Day_Hour ,Table_7. STATION_CODE'')';
EXEC sp_executesql @TSQL;
假设您有一些带有字符串的动态 SQL:
'SELECT * FROM foo WHERE bar = ''i am a string'';'
-- ^^ ^^
-- || ||
-- notice the double quotes
现在让我们用 OPENQUERY
来做,在动态 SQL 中(你的情况):
'SELECT * FROM OPENQUERY (VFDB,''SELECT * FROM foo WHERE bar = ''''i am a string'''';'')'
-- ^^ ^^^^
-- || ||||
-- double quotes escaped double quotes => 4 quotes
您在字符串中嵌套了查询,因此每次添加嵌套级别时,您都必须将引号加倍以避免关闭较高的嵌套级别。
强烈反对,因为调试起来真的很痛苦,正如您猜到的那样,更不用说变量连接可能是多么混乱(但是您已经为此使用了 5 个引号,所以您已经知道了:))。
我修复引号的尝试(无法测试,所以也许我在某些时候搞砸了):
DECLARE @TSQL nvarchar(max); Declare @STATION_CODE varchar(max); Declare @STATION_CODE_PREV varchar(max);
SET @STATION_CODE='1600020'; SET @STATION_CODE_PREV='1600007'; SET @TSQL='SELECT * FROM OPENQUERY (VFDB,''''SELECT COUNT(TABLE_7.FIFO) AS FIFO_COUNT,TABLE_7.FIFO,TABLE_7.Day_Hour ,TABLE_7.Station_Code,''''FIFO'''' AS Element FROM ( select CAST(CASE WHEN TABLE_6 .BCD_PRV2_EXIT=TABLE_5 .BCD_PRV2 THEN ''''1'''' ELSE ''''0'''' END AS INT) FIFO, case when datepart(hour,TABLE_6.CREATION_DATE_E3 )<10
then
''''0''''
+Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':00 - ''''+''''0''''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':59''''
else
Right (Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':00 - ''''
+Right(Cast(datepart(hour,TABLE_6.CREATION_DATE_E3 + 100) As Varchar) ,2)+'''':59''''
end As Day_Hour ,TABLE_6.Station_Code As Station_Code from
( select T1_ENTRY.RANK1_ENTRY AS T5_R1, T1_ENTRY.BCD_PRV1,T1_ENTRY.CREATION_DATE_E1,T2_ENTRY.RANK2_ENTRY , T2_ENTRY.BCD_PRV2 ,T2_ENTRY.CREATION_DATE_E2 from
(
select MFG_UNIT_NUM as BCD_PRV1,CREATION_DATE AS CREATION_DATE_E1 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''''REFRIGERATOR'''', NULL, '''''+ @STATION_CODE +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T1_ENTRY LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2,CREATION_DATE AS CREATION_DATE_E2,ROW_NUMBER()over(order by Creation_Date) as RANK2_ENTRY
FROM dbo.DAW_FN_STATS_TLDTLRAW(115, ''''REFRIGERATOR'''', NULL, '''''+ @STATION_CODE_PREV +''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T2_ENTRY ON T1_ENTRY.RANK1_ENTRY=T2_ENTRY.RANK2_ENTRY-1
) TABLE_5
LEFT JOIN
( select T3_EXIT.RANK1_EXIT AS T6_R1, T3_EXIT.BCD_PRV1_EXIT,T3_EXIT.CREATION_DATE_E3,T4_EXIT.RANK2_EXIT , T4_EXIT.BCD_PRV2_EXIT ,T4_EXIT.CREATION_DATE_E4,T3_EXIT.Station_Code from
(
select MFG_UNIT_NUM as BCD_PRV1_EXIT,CREATION_DATE AS CREATION_DATE_E3 ,ROW_NUMBER()over(order by Creation_Date) as RANK1_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''''REFRIGERATOR'''', NULL, '''''+@STATION_CODE+''''',NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T3_EXIT LEFT JOIN
(
select MFG_UNIT_NUM as BCD_PRV2_EXIT,CREATION_DATE AS CREATION_DATE_E4,ROW_NUMBER()over(order by Creation_Date) as RANK2_EXIT,STATION_CODE as STATION_CODE
FROM dbo.DAW_FN_STATS_TLDTLRAW(115,''''REFRIGERATOR'''', NULL,'''''+@STATION_CODE_PREV+''''', NULL,Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0),Dateadd(hh,1, Dateadd(HOUR, Datediff(HOUR,0,GETDATE()),0)))RAWDTL
) T4_EXIT ON T3_EXIT.RANK1_EXIT=T4_EXIT.RANK2_EXIT-1 ) TABLE_6 ON TABLE_5.BCD_PRV2=TABLE_6.BCD_PRV2_EXIT )TABLE_7 GROUP BY TABLE_7.FIFO,TABLE_7.Day_Hour ,Table_7. STATION_CODE'')';
EXEC sp_executesql @TSQL;
您已经得到了答案,所以这只是一个提示,您以后如何轻松解决此类问题。
declare @sql_string varchar(100)
set @sql_string = 'SELECT * FROM OPENQUERY (VFDB,''SELECT * FROM foo WHERE bar = ''''i am a string'''';'')'
select @sql_string --> This here will let you see how your string looks like