Проблема преобразования в параметре datetime в SQL Server 2008 - PullRequest
1 голос
/ 30 июня 2011

У меня есть отчет сервера sql, в котором есть параметры datedate и enddate datetime, но когда я указываю в них datetime, отчет показывает ошибку

An error has occurred during report processing.
Exception has been thrown by the target of an invocation.
Conversion failed when converting date and/or time from character string.

Параметр startdate имеет значение 6/22/2011 12:00:00 AM когда задано в качестве параметра отчета в коде C #, мой код хранимой процедуры -

create PROCEDURE Price
@Startdate datetime = null,
@Enddate datetime = null    
AS    
declare @sql varchar(8000)
set @sql = 'SELECT CommodityPrice.dtm_Date FROM Commodity 
INNER JOIN CommodityPrice ON Commodity.int_CommodityId = CommodityPrice.int_CommodityId where Commodity.vcr_HSCode is not null ' 

IF (@Startdate <> '')
BEGIN   
        SET @sql = @sql + ' and CommodityPrice.dtm_Date >= '+ @Startdate

END
IF (@Enddate <> '')
BEGIN   
        SET @sql = @sql + ' and CommodityPrice.dtm_Date <= '+ @Enddate
END

set @sql = @sql+ ' order by CommodityPrice.dtm_Date desc'

exec (@sql)

Как я могу удалить эту проблему?Я создаю динамический sql, потому что у меня есть и другие параметры.

Ответы [ 3 ]

3 голосов
/ 30 июня 2011

Мой совет;не объединять ввод; p (как всегда).Вы все еще можете использовать параметры с EXEC, особенно с sp_ExecuteSQL.Это позволит избежать всех проблем, и , допускающих повторное использование плана запросов.

НИКОГДА не объединять пользовательский ввод, даже в TSQL.ВСЕГДА используйте параметры, если только абсолютно невозможно сделать.

В качестве тривиального примера (в частности, чтобы показать, что имена параметров не должны совпадать):

declare @a int = 15, @b datetime = GETUTCDATE()

declare @sql nvarchar(400) = 'select @x, @y'

exec sp_executeSql @sql, N'@x int, @y datetime', @a, @b

мы передаем @a и @b в качестве параметров (сопоставление с @x и @y) в SQL в @sql и выполняем безопасным, повторно используемым, кэшируемым способом.

1 голос
/ 30 июня 2011

Вы должны сначала преобразовать значение в varchar, прежде чем объединять

CONVERT(varchar(30), @Enddate, 121)

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

Третья проблема заключается в том, что для динамического SQL вам необходимо предоставить права на таблицы. Без этого вызывающей стороне нужны только права на хранимую процедуру.

Наконец, вам не нужен динамический SQL

create PROCEDURE Price
   @Startdate datetime = null,
   @Enddate datetime = null    
AS    
SET NOCOUNT ON;

SET @Startdate = ISNULL(@Startdate, '19000101');
SET @Enddate = ISNULL(NULLIF(@Enddate, '19000101'), '99991231');

SELECT CommodityPrice.dtm_Date FROM Commodity 
INNER JOIN CommodityPrice ON Commodity.int_CommodityId = CommodityPrice.int_CommodityId where Commodity.vcr_HSCode is not null ' 

and CommodityPrice.dtm_Date >= @Startdate
and CommodityPrice.dtm_Date <= @Enddate
order by CommodityPrice.dtm_Date desc
GO
0 голосов
/ 30 июня 2011

Вы также можете оставить 'arround date-параметр

tableName.DateInTable> @ReportDateParameter

Вот что у меня работает в проекте.

Извините - только что увидел, что ваш sql связан вместе - поэтому ваш DateParameter должен быть преобразован в строку - как указано в ответе выше.

...