2013-02-04 49 views
-1

我收到以下錯誤,當我執行我的存儲過程:錯誤在SQL存儲過程

消息102,級別15,狀態1,行6
附近有語法錯誤「2011」。
(1行(S)的影響)

這裏是存儲過程:

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

你的#temp表有4列,但你的插入語句只有3個。所以一旦你解決了分析問題,你會在插入時得到一個錯誤。您需要明確地爲日期列添加值,爲其設置默認值,或者在插入時使用適當的列列表並將其保留。 –

回答

1

這是''2011%''的語法。這不是有效的日期。 %是通配符意味着編譯器無法知道在WHERE子句中要比較的內容。您需要使用實際日期:即'2011_01_01'',因此編譯器可以知道要比較的內容

+0

如果'delivered_date'不是日期/日期時間列,但varchar? –

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 
+0

我其實最初嘗試過,並且出現錯誤。我在其他存儲過程中使用了這種方法,並且它工作得很好。我同意約會。你的代碼是正確的執行方式。我將納入這一變化。 –

5

除了您的日期比較的邏輯錯誤其他人指出,你目前的問題是一個語法錯誤。

既然你已經有了另一個動態sql語句中包含的動態sql語句......你需要雙重轉義所有的單引號......你在大多數查詢中所做的除外以下行:

where delivered_date > ''2011%'' order by Style '')' 

正確轉義,應該是:

where delivered_date > ''''2011%'''' order by Style '')' 

這就提出了一個問題......你爲什麼要建立字符串動態執行,而不是隻直接調用語句?

+0

如上所述,當我用fqn運行它時,會導致很多問題。這在過去運作良好。 –