从字符串转换日期时间时出现错误消息转换失败
Error message Conversion failed when converting datetime from character string
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 代码的存储过程。
(请注意,我删除了很多我认为与我遇到的错误无关的代码)
执行时出现以下错误。
Conversion failed when converting datetime from character string.
我的参数具有以下格式的值
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 +')'
我可以应用哪种最佳日期格式来避免错误。
您应该通过 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 语句更容易阅读。类型问题通过参数处理。而且,查询计划更容易隐藏。不幸的是,参数仅适用于常量,不适用于列或 table 名称,例如。
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 代码的存储过程。 (请注意,我删除了很多我认为与我遇到的错误无关的代码) 执行时出现以下错误。
Conversion failed when converting datetime from character string.
我的参数具有以下格式的值
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 +')'
我可以应用哪种最佳日期格式来避免错误。
您应该通过 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 语句更容易阅读。类型问题通过参数处理。而且,查询计划更容易隐藏。不幸的是,参数仅适用于常量,不适用于列或 table 名称,例如。