【问题标题】:Conversion problem in datetime parameter in sql server 2008sql server 2008中日期时间参数的转换问题
【发布时间】:2011-06-30 07:40:45
【问题描述】:

我有一个 sql server 报告,其中包含 startdate 和 enddate 日期时间参数,但是当我在其中指定日期时间时,报告显示错误

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,因为我还有一些其他参数。

【问题讨论】:

    标签: c# sql-server-2008 stored-procedures reporting-services


    【解决方案1】:

    我的建议;不要连接输入 ;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,并以安全、可重用、可缓存的方式执行。

    【讨论】:

      【解决方案2】:

      在连接之前,您必须先将值转换为 varchar

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

      您还有第二个问题,即日期时间永远不能是空字符串:如果您分配了一个空字符串,那么这将成为 1900 年 1 月 1 日的午夜(为零)

      第三个问题是,对于动态 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
      

      【讨论】:

      • 考虑到空字符串的问题 - 也许最好将 DateTime 值作为字符串提交给报告。那么就可以发送 string.Empty.
      • @Gambrinus:不是真的。如果你混合使用字符串和日期时间,你会因为 DMY、MDY 等而出现意外的转换错误。
      • 我正在使用动态 SQL,因为我有 7 个其他类型的 int、varchar 和 bit 参数
      【解决方案3】:

      您也可以将 ' 留在日期参数周围

      tableName.DateInTable> @ReportDateParameter
      

      这就是我在项目中的作用。

      抱歉 - 刚刚看到您的 sql 链接在一起 - 因此您的 DateParameter 必须转换为字符串 - 如上面的答案所述。

      【讨论】:

        猜你喜欢
        • 2019-08-01
        • 1970-01-01
        • 2016-05-11
        • 2013-10-31
        • 1970-01-01
        • 1970-01-01
        • 2017-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多