2011-04-04 124 views
0

我有一個查詢,它的工作原理,當它是這樣運行:SQL查詢工作正常,但無法在動態

declare @nvRecipients varchar(4000) 
    ,@CustomerCode varchar(6) 
    ,@start datetime 
    ,@end datetime 

SELECT @CustomerCode = '10095' 
     ,@start = '01/01/2011' 
     ,@end = '02/01/2011' 

    Select substring(PSD.DTSItemCode,1,4) As ItemCompanyCode , 
    convert(varchar(50),Cast(Sum(PSD.Quantity) as money),1) As TotalShipped 
    From [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipHeader PSH 
    Inner Join [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipsDetail PSD On PSH.PKSNumber = PSD.PKSNumber 
    Where Cast (PKSDate As DateTime) >= @start 
    And Cast (PKSDate As DateTime) <= @end 
    And PSD.Quantity > 0 
    And (CompanyCode = @CustomerCode) 
    Group By substring(PSD.DTSItemCode,1,4) 
    Order By substring(PSD.DTSItemCode,1,4) 

語法錯誤轉換日期時間從 字符串引發錯誤。

 Set @nvQuery = ' Select substring(PSD.DTSItemCode,1,4) As ItemCompanyCode , ' 
    Set @nvQuery = @nvQuery + ' convert(varchar(50),Cast(Sum(PSD.Quantity) as money),1) As TotalShipped ' 
    Set @nvQuery = @nvQuery + ' From [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipHeader PSH ' 
    Set @nvQuery = @nvQuery + ' Inner Join [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipsDetail PSD On PSH.PKSNumber = PSD.PKSNumber ' 
    Set @nvQuery = @nvQuery + ' Where Cast (PKSDate As DateTime) >= ''' + @start + ''' ' 
    Set @nvQuery = @nvQuery + ' And Cast (PKSDate As DateTime) <= ''' + @end + ''' ' 
    Set @nvQuery = @nvQuery + ' And PSD.Quantity > 0 ' 
    Set @nvQuery = @nvQuery + ' And (CompanyCode = ''' + @CustomerCode + ''') ' 
    Set @nvQuery = @nvQuery + ' Group By substring(PSD.DTSItemCode,1,4) ' 
    Set @nvQuery = @nvQuery + ' Order By substring(PSD.DTSItemCode,1,4) ' 

有人能看到我的錯誤:

當一個存儲過程,其中@customercode,@啓動和@end被提供的參數內跑了這個樣子?我似乎無法找到它。數據全部用ISDATE()檢出。

+0

我還沒有嘗試過,但對於初學者,您顯式轉換爲datetime在您的查詢,但隱含(未讀)在您的動態地創建查詢 – 2011-04-04 20:16:51

+0

是啊,這是一個錯誤(的變化我已經試過了雙向)。我已經將問題編輯回原來的方式,在兩個地方投射。 – MAW74656 2011-04-04 20:17:43

+0

您已將日期時間轉換爲數量。我懷疑你的意圖是什麼。 – 2011-04-04 20:19:20

回答

3

如果它們是日期,則需要將它們轉換爲varchar以附加到查詢。

不能連接日期時間爲一個字符串W/O第一投射它:

Set @nvQuery = @nvQuery + ' And Cast(PKSDate As DateTime) <= ''' + CAST(@end AS VARCHAR(20)) + ''' ' 

Set @nvQuery = ' Select substring(PSD.DTSItemCode,1,4) As ItemCompanyCode , ' 
    Set @nvQuery = @nvQuery + ' convert(varchar(50),Cast(Sum(PSD.Quantity) as money),1) As TotalShipped ' 
    Set @nvQuery = @nvQuery + ' From [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipHeader PSH ' 
    Set @nvQuery = @nvQuery + ' Inner Join [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipsDetail PSD On PSH.PKSNumber = PSD.PKSNumber ' 
    Set @nvQuery = @nvQuery + ' Where Cast (PKSDate As DateTime) >= ''' + CONVERT(varchar(20), @start, 101) + ''' ' 
    Set @nvQuery = @nvQuery + ' And Cast (PKSDate As DateTime) <= ''' + CONVERT(varchar(20), @end, 101) + ''' ' 
    Set @nvQuery = @nvQuery + ' And PSD.Quantity > 0 ' 
    Set @nvQuery = @nvQuery + ' And (CompanyCode = ''' + @CustomerCode + ''') ' 
    Set @nvQuery = @nvQuery + ' Group By substring(PSD.DTSItemCode,1,4) ' 
    Set @nvQuery = @nvQuery + ' Order By substring(PSD.DTSItemCode,1,4) ' 
+0

那麼,如果我將PKSDate強制轉換爲日期時間,並且參數@end已經是日期時間,那我是不是在比較日期? – MAW74656 2011-04-04 20:24:51

+0

您嘗試將日期連接到字符串...將不起作用 – SQLMason 2011-04-04 20:25:54

+1

您需要:<='''+ cast(@end as varchar(20))... – SQLMason 2011-04-04 20:26:35

2

要保存自己很多的麻煩,你可以使用動態SQL參數爲好,是! - 參數,就像在真正的查詢中一樣。

Set @nvQuery = ' Select substring(PSD.DTSItemCode,1,4) As ItemCompanyCode , ' 
    Set @nvQuery = @nvQuery + ' convert(varchar(50),Cast(Sum(PSD.Quantity) as money),1) As TotalShipped ' 
    Set @nvQuery = @nvQuery + ' From [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipHeader PSH ' 
    Set @nvQuery = @nvQuery + ' Inner Join [AVANTISERVER\NCL_MASTER].AVANTI.dbo.PackingSlipsDetail PSD On PSH.PKSNumber = PSD.PKSNumber ' 
    Set @nvQuery = @nvQuery + ' Where Cast (PKSDate As DateTime) >= @start ' 
    Set @nvQuery = @nvQuery + ' And Cast (PKSDate As DateTime) <= @end ' 
    Set @nvQuery = @nvQuery + ' And PSD.Quantity > 0 ' 
    Set @nvQuery = @nvQuery + ' And (CompanyCode = @CustomerCode) ' 
    Set @nvQuery = @nvQuery + ' Group By substring(PSD.DTSItemCode,1,4) ' 
    Set @nvQuery = @nvQuery + ' Order By substring(PSD.DTSItemCode,1,4) ' 

而是通過

EXEC (@nvQuery) 

運行它的使用形式

exec sp_executeSQL @nvQuery, 
    N'@start datetime,@end datetime,@customerCode varchar(6)', --list of params 
    @start, @end, @customerCode -- params, matching list 

這周圍得到各種字符串操作,投/格式問題。例如

declare @start datetime,@end datetime,@customerCode varchar(6) 
select @start = getdate(), @end = getdate()+2, @customerCode = 'TEST' 

set @nvQuery ... -- build the statement 

exec sp_executeSQL @nvQuery, 
    N'@start datetime,@end datetime,@customerCode varchar(6)', --list of params 
    @start, @end, @customerCode -- params, matching list 
+0

這是否可以在SQL Server 2000中工作?還有,我在哪裏分配值? – MAW74656 2011-04-04 20:36:02

+0

@MAW - 是的,它在2000年有效。在調用存儲過程之前,你可以像往常一樣將值賦給任何變量,請參閱更新後的答案。它更健壯,更不易於SQL注入 – RichardTheKiwi 2011-04-04 20:38:56

+0

所以技巧是我必須聲明變量兩次,一旦在程序en totale中,然後在N'語句中再次出現。Ok,我明白了。 – MAW74656 2011-04-04 20:46:35