【问题标题】:Error message Conversion failed when converting datetime from character string错误消息从字符串转换日期时间时转换失败
【发布时间】:2016-08-06 03:39:29
【问题描述】:
    ALTER  PROCEDURE [dbo].[TEST_01]       
     (
        @StartDate  DateTime,
        @EndDate    DateTime
     )
    AS      
    BEGIN      
      SET NOCOUNT ON;  
      Declare @sql as nvarchar(MAX);
      SET @sql = @sql + ';WITH CTE_ItemDetails
                MAX(D.Name) as Name,
                SUM(ISNULL(DT.col1, 0)) AS col1,
                SUM(ISNULL(DT.col2, 0)) AS col2,
                SUM(ISNULL(DT.col3, 0)) AS col3,
                GROUPING(D.ItemType) AS ItemTypeGrouping
            FROM Items D
                INNER JOIN Details DT ON DT.ItemId = D.ItemId
                INNER JOIN Report R ON R.ReportId = DT.ReportId
                where 1=1'
            SET @sql = @sql + ' AND (R.ReportDate >= ' + @StartDate + 'AND  R.ReportDate <=' + @EndDate +')' 

            IF @someOtherVariable is not  null
            SET @sql = @sql + ' AND R.someColumn IN (''' +replace(@someOtherVariableValues,',','')+''+')' 

            SET @sql = @sql + 'SELECT col1, col2, col3 FROM CTE_ItemDetails'
            EXECUTE (@sql)  
    END

我有一个类似于上面的 T-SQL 代码的存储过程。 (请注意,我删除了许多我认为与我遇到的错误无关的代码) 执行时出现以下错误。

从字符串转换日期时间时转换失败。

我的参数具有以下格式的值

exec TEST_01 @StartDate=N'4/1/2016 12:00:00 AM',@EndDate=N'4/30/2016 12:00:00 AM'

看来问题在于我在下面一行动态设置 SQL 语句的方式

SET @sql = @sql + ' AND (R.ReportDate >= ' + @StartDate + 'AND  R.ReportDate <=' + @EndDate +')' 

我可以应用什么最好的日期格式来避免错误。

【问题讨论】:

  • 你需要引用日期,你应该改成@sql + ' AND (R.ReportDate &gt;= ''' + @StartDate + ''' AND R.ReportDate &lt;= ''' + @EndDate + ''')'
  • @Siyual 这会返回相同的错误

标签: sql tsql sql-server-2005


【解决方案1】:

你应该通过sp_executesql使用参数。

但你的直接问题是这一行:

    SET @sql = @sql + ' AND (R.ReportDate >= ' + @StartDate + 'AND  R.ReportDate <=' + @EndDate +')' 

它应该看起来更像:

SET @sql = @sql + ' AND (R.ReportDate >= ''' + convert(varchar(10), @StartDate, 121) + ''' AND R.ReportDate <= ''' + convert(varchar(10), @EndDate, 121) +''')' ;

注意包含对字符串的显式类型转换和双单引号,因此日期文字不会被解释为 2016 - 04 - 14(即 2000)。

使用参数的更好方法如下:

    SET @sql = @sql + ' AND (R.ReportDate >= @StartDate AND R.ReportDate <= @EndDate)' ;

. . .
exec sp_executesql @sql, N'@StartDate date, @EndDate date)', @StartDate = @StartDate, @EndDate = @EndDate;

SQL 语句更容易阅读。类型问题通过参数处理。而且,查询计划更容易隐藏。不幸的是,参数仅适用于常量,例如,不适用于列名或表名。

【讨论】:

  • 如果我使用sp_executesql 并传递一个未添加到@sql 字符串的参数,因为它被发现为空或空,会发生什么?我问这个是因为我添加了更多参数(我最初发布的脚本中没有显示)。我已经更新了我的代码以显示这一点。
  • @StackTrace 。 . .如果参数是在第二个和第三个参数中声明的,那么它是否在 SQL 字符串中都没关系。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多