2013-02-25 36 views
2

對於此代碼,當我引入2個日期變量時出現錯誤代碼錯誤。日期時間變量的動態sql語法問題

錯誤是

Msg 137, Level 15, State 1, Line 8 
Must declare the scalar variable "@STARTDATE". 
Msg 137, Level 15, State 1, Line 9 
Must declare the scalar variable "@ENDDATE". 

任何想法如何克服這個作爲我的大腦現在是正式死了嗎?

DECLARE 
    @Query1 AS NVARCHAR(MAX), 
    @Startdate DATETIME, 
    @Enddate DATETIME 

SET @STARTDATE = '10-JAN-2012' 
SET @ENDDATE = '11-JAN-2012' 

SET @Query1 = ' 

;WITH CTE AS 
(
    select COALESCE(PT.[description] , ''Grand Total'') AS [Transaction Type], 
      Sum (AI.PRICE_INC_VAT) AS [AMOUNT (ú) CREDIT], 
      P.[DESCRIPTION] AS [PRODUCT TYPE] 

From [dbo].[T1] C 
join [dbo].[T2] S on S.[Customer_ID]=C.[Customer_ID] 
join [dbo].[T3] SO on SO.[SITE_ID]=S.[SITE_ID] 
join [dbo].[T4] OI on OI.[ORDER_ID]=SO.[SITE_ORDER_ID] 
left join [dbo].[T5] P on P.[PRODUCT_ID]=OI.[PRODUCT_ID] 
JOIN [dbo].[T6] AI ON AI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID 
JOIN [T7] JBAI ON JBAI.ACTION_ITEM_ID = AI.ACTION_ITEM_ID 
JOIN T8 JB ON JB.JOB_BATCH_ID = JBAI.JOB_BATCH_ID 
JOIN [T9] PA on PA.PAYMENT_ID=JB.PAYMENT_ID 
LEFT JOIN [T10] CU ON JB.CUSTOMER_USER_ID = CU.CUSTOMER_USER_ID 
JOIN [T11] PT ON PT.PAYMENT_TYPE_ID=PA.PAYMENT_TYPE_ID 
LEFT JOIN [T12] ON SU.SYS_USER_ID=JB.SYS_USER_ID 

where P.[PRODUCT_CATEGORY_ID]= ''PADS'' 
    and C.COMPANY_ID= ''19992'' 
    and PA.DATE_RECEIVED BETWEEN @Startdate AND @Enddate 

group by PT.DESCRIPTION, P.DESCRIPTION 
)' 

回答

6

您的參數超出了您的SQL查詢範圍。您需要將參數傳遞給sql字符串。你會發現,你還必須投下的參數作爲varchar所以它可以連接在一起字符串:

DECLARE 
    @Query1 AS NVARCHAR(MAX), 
    @Startdate DATETIME, 
    @Enddate DATETIME 

SET @STARTDATE = '10-JAN-2012' 
SET @ENDDATE = '11-JAN-2012' 

SET @Query1 = ' 

;WITH CTE AS 
(
    select COALESCE(PT.[description] , ''Grand Total'') AS [Transaction Type], 
      Sum (AI.PRICE_INC_VAT) AS [AMOUNT (ú) CREDIT], 
      P.[DESCRIPTION] AS [PRODUCT TYPE] 

From [dbo].[T1] C 
join [dbo].[T2] S on S.[Customer_ID]=C.[Customer_ID] 
join [dbo].[T3] SO on SO.[SITE_ID]=S.[SITE_ID] 
join [dbo].[T4] OI on OI.[ORDER_ID]=SO.[SITE_ORDER_ID] 
left join [dbo].[T5] P on P.[PRODUCT_ID]=OI.[PRODUCT_ID] 
JOIN [dbo].[T6] AI ON AI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID 
JOIN [T7] JBAI ON JBAI.ACTION_ITEM_ID = AI.ACTION_ITEM_ID 
JOIN T8 JB ON JB.JOB_BATCH_ID = JBAI.JOB_BATCH_ID 
JOIN [T9] PA on PA.PAYMENT_ID=JB.PAYMENT_ID 
LEFT JOIN [T10] CU ON JB.CUSTOMER_USER_ID = CU.CUSTOMER_USER_ID 
JOIN [T11] PT ON PT.PAYMENT_TYPE_ID=PA.PAYMENT_TYPE_ID 
LEFT JOIN [T12] ON SU.SYS_USER_ID=JB.SYS_USER_ID 

where P.[PRODUCT_CATEGORY_ID]= ''PADS'' 
    and C.COMPANY_ID= ''19992'' 
    and PA.DATE_RECEIVED BETWEEN '+ convert(varchar(10), @Startdate, 120) 
    + ' AND '+ convert(varchar(10), @Enddate, 120) +' 

group by PT.DESCRIPTION, P.DESCRIPTION 
)' 

我不知道爲什麼你使用動態SQL這個過程雖然。

;WITH CTE AS 
(
    select COALESCE(PT.[description] , 'Grand Total') AS [Transaction Type], 
      Sum (AI.PRICE_INC_VAT) AS [AMOUNT (ú) CREDIT], 
      P.[DESCRIPTION] AS [PRODUCT TYPE] 

From [dbo].[T1] C 
join [dbo].[T2] S on S.[Customer_ID]=C.[Customer_ID] 
join [dbo].[T3] SO on SO.[SITE_ID]=S.[SITE_ID] 
join [dbo].[T4] OI on OI.[ORDER_ID]=SO.[SITE_ORDER_ID] 
left join [dbo].[T5] P on P.[PRODUCT_ID]=OI.[PRODUCT_ID] 
JOIN [dbo].[T6] AI ON AI.ORDER_ITEM_ID = OI.ORDER_ITEM_ID 
JOIN [T7] JBAI ON JBAI.ACTION_ITEM_ID = AI.ACTION_ITEM_ID 
JOIN T8 JB ON JB.JOB_BATCH_ID = JBAI.JOB_BATCH_ID 
JOIN [T9] PA on PA.PAYMENT_ID=JB.PAYMENT_ID 
LEFT JOIN [T10] CU ON JB.CUSTOMER_USER_ID = CU.CUSTOMER_USER_ID 
JOIN [T11] PT ON PT.PAYMENT_TYPE_ID=PA.PAYMENT_TYPE_ID 
LEFT JOIN [T12] ON SU.SYS_USER_ID=JB.SYS_USER_ID 

where P.[PRODUCT_CATEGORY_ID]= 'PADS' 
    and C.COMPANY_ID= '19992' 
    and PA.DATE_RECEIVED BETWEEN @Startdate AND @Enddate 

group by PT.DESCRIPTION, P.DESCRIPTION 
) 
+0

我會補充說,到目前爲止所問的內容似乎對動態SQL根本沒有任何實際需求 - 一個帶有@ @Stardate和\ @Enddate參數的存儲過程將會很好。 – 2013-02-25 19:56:36

+0

更好的是,使用sp_executesql,以便不串聯字符串。 – 2013-02-25 19:58:01

+0

@RossPresser我在更新我的答案時,包括註釋,當你評論。 – Taryn 2013-02-25 19:59:28

2

如果確實需要動態SQL,你應該做到以下幾點:這可以在不使用動態SQL可以容易地進行

-- USE UNAMBIGUOUS FORMATS PLEASE! 

SET @STARTDATE = '20120110'; 
SET @ENDDATE = '20120111'; 

SET @Query1 = ';WITH CTE AS 
... 
    and PA.DATE_RECEIVED BETWEEN @STARTDATE AND @ENDDATE 
    group by PT.DESCRIPTION, P.DESCRIPTION 
)'; 

EXEC sp_executesql 
    @Query1, 
    N'@STARTDATE DATETIME, @ENDDATE DATETIME', 
    @STARTDATE, @ENDDATE; 

但是除非我失去了一些東西沒有必要在這裏爲動態SQL。