执行存储过程时出现以下错误:
Msg 102,Level 15,State 1,Line 6
'2011'附近的语法不正确。
(受影响的1行)
这是存储过程:
ALTER PROCEDURE [dbo].[DeliveryFileNames]
AS
BEGIN
SET NOCOUNT ON;
declare @SQL nvarchar(4000)
Create Table #DelivTemp(
Style nvarchar(50),
Material nvarchar(50),
Filename nvarchar(100),
delivered_date date)
set @SQL=
N'insert into #DelivTemp
Select distinct Style,Material,filename
from OPENQUERY(GCS_PRODUCTION,
''SELECT LEFT(FILENAME,locate(''''_'''',FILENAME)-1)as Style,
substring_index(filename,''''_'''',2)as Material,filename,
delivered_date FROM view_delivery_log
where delivered_date > ''2011%'' order by Style '')'
exec (@SQL)
drop table dbo.DelivFN
Select * into dbo.DelivFN
from #DelivTemp
END
我正在使用OpenQuery从SQL Server 2008 R2上的链接服务器更新SQL表。
我知道下划线是一个真正的问题,但我尝试了很多选项,包括\
,%
以及单引号和双引号。
无论我得到相同的结果。我可以独立于存储过程运行查询并获得正确的结果。多次引用的文件名字段格式为00000000_ABC4_A.png
。我使用下划线来标识出于报告目的所需的文件名组件。
答案 0 :(得分:5)
除了使用其他人指出的%
进行日期比较的逻辑错误之外,您当前的问题还是语法错误。
由于你有一个动态sql语句包含在另一个动态sql语句中...你需要双重转义你所有的单引号...你在大多数情况下做了查询,但以下行除外:
where delivered_date > ''2011%'' order by Style '')'
正确逃脱,将是:
where delivered_date > ''''2011%'''' order by Style '')'
提出了一个问题......为什么要构建要动态执行的字符串,而不是直接调用语句?
答案 1 :(得分:1)
它是' 2011%''的语法。这不是有效日期。 %是通配符意味着编译器无法知道WHERE子句中要比较的内容。您需要使用实际日期:即' 2011_01_01''' 2011_01_01''所以编译器可以知道要与
进行比较的内容答案 2 :(得分:0)
我相信存储的proc exec
在不同的会话下运行,因此无论如何你都无法访问临时表。因此,如果您运行sql语句并不重要。您可以随时使用YEAR(delivered_date) > 2011
。
另一种方法是使用链接服务器的fqn一起选择并绕过临时表:
SELECT LEFT(FILENAME,locate('_',FILENAME)-1)as Style,
substring_index(filename,'_',2)as Material,filename,delivered_date
FROM [linked_server_name].[db_name].[dbo].view_delivery_log
into dbo.DelivFN