如何在连接的 SQL 查询字符串中 convert/cast 列数据类型

How to convert/cast column data type in concatenated SQL query string

我在我的存储过程中定义了以下变量

@StartDate  DateTime,
@EndDate    DateTime,

我将 sql 设置为动态执行,因此在构建查询 where 子句时,我有以下行。

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

当我执行存储过程时,上面的行抛出下面的错误

Conversion failed when converting datetime from character string.

如果我将变量数据类型更改为 NVARCHAR(MAX),程序会成功执行,但随后 returns 没有行,因为日期 comparison/matching 失败。

ReportDate 列的数据类型为 datetime,并且包含此格式的数据 2014-06-01 00:00:00.000

如您所见,我在构建查询时尝试过转换列,但这不起作用。

问题不在于 ReportDate,而是当您尝试将 DateTime 参数与 nvarchar sql 语句连接时。该问题可以相当简单地重现:

DECLARE @SQL NVARCHAR(MAX) = 'Some text' + GETDATE();

解决此问题的错误方法是将日期时间参数转换为字符串,以便它可以与字符串连接,例如

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 并以这种方式传递正确类型的参数,这将避免转换问题。例如

SET @sql = @sql + 'AND r.ReportDate >= @StartDateParam AND r.ReportDate <= @EndDateParam';

EXECUTE sp_executesql 
    @sql, 
    N'@StartDateParam DATETIME, @EndDateParam DATETIME',
    @StartDateParam = @StartDate,
    @EndDateParam = @EndDate