SQL-запрос работает нормально, но не работает при динамическом - PullRequest
0 голосов
/ 05 апреля 2011

У меня есть запрос, который работает при его запуске следующим образом:

  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) 

но выдает ошибку

Ошибка синтаксиса при преобразовании даты и времени из строка символов.

При запуске таким образом в хранимой процедуре, где @customercode, @start и @end предоставляют параметры:

       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) '

Кто-нибудь может увидеть мою ошибку? Я не могу найти это. Все данные проверяются с помощью ISDATE ().

Ответы [ 2 ]

3 голосов
/ 05 апреля 2011

Если это даты, вам нужно привести их к varchar, чтобы добавить к запросу.

Нельзя объединить дату и время со строкой без ее приведения:

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) '
2 голосов
/ 05 апреля 2011

Чтобы избавить себя от лишних хлопот, вы можете использовать параметры и с динамическим 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
...