SQL存储过程出错

时间:2013-02-04 21:45:53

标签: sql

执行存储过程时出现以下错误:

  

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。我使用下划线来标​​识出于报告目的所需的文件名组件。

3 个答案:

答案 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