我的存储过程中定义了以下变量
@StartDate DateTime,
@EndDate DateTime,
我设置sql是动态执行的,所以在构造查询时where子句我有以下行。
SET @sql = @sql + ' AND (convert(datetime, R.ReportDate, 121) >= ' + @StartDate + 'AND convert(datetime, R.ReportDate, 121) <=' + @EndDate +')'
当我执行存储过程时,上面的行会抛出错误
从字符串转换日期时转换失败。
如果我将变量数据类型更改为NVARCHAR(MAX)
,则过程成功执行但不返回任何行,因为日期比较/匹配失败。
ReportDate列的数据类型为datetime,其格式为2014-06-01 00:00:00.000
正如您所看到的,我在构建查询时尝试转换列,但这并不起作用。
答案 0 :(得分:4)
问题不在于ReportDate
,而是在尝试将您的DateTime参数与nvarchar sql语句连接在一起时。问题可以通过以下方式简单地再现:
DECLARE @SQL NVARCHAR(MAX) = 'Some text' + GETDATE();
解决此问题的错误方法是将datetime参数转换为字符串,以便它可以与字符串连接,例如
SET @sql = @sql + ' AND r.ReportDate >= CONVERT(DATETIME, '''
+ CONVERT(VARCHAR(10), @StartDate, 112)
+ ''', 112) AND r.ReportDate <= CONVERT(DATETIME, ''' +
+ CONVERT(VARCHAR(10), @EndDate, 112)
+ ''', 112)';
N.B。为了完整答案,我将此包括在内,并且绝不支持这种方法
解决此问题的正确方法是使用sp_executesql
并以这种方式传递正确输入的参数,这样可以避免转换问题。 e.g。
SET @sql = @sql + 'AND r.ReportDate >= @StartDateParam AND r.ReportDate <= @EndDateParam';
EXECUTE sp_executesql
@sql,
N'@StartDateParam DATETIME, @EndDateParam DATETIME',
@StartDateParam = @StartDate,
@EndDateParam = @EndDate