2016-04-15 68 views
0

我在存储过程中的定义的变量/施放列数据类型如何转换在串联SQL查询字符串

@StartDate DateTime, 
@EndDate DateTime, 

我设置SQL动态地执行,所以构建查询在当子句我有以下行。

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

当我执行存储过程中,线的上方抛出下面

转换中的误差从字符串变换日期时间时失败。

如果我将变量数据类型更改为NVARCHAR(MAX),该过程将成功执行,但由于日期比较/匹配失败而不返回任何行。

ReportDate列数据类型的日期时间,在这种格式2014-06-01 00:00:00.000

有数据正如你可以看到我已经尝试构建我的查询时转换列,但不工作。

+3

SQL Server *中的DATETIME列没有任何格式!* - 它是一个8字节的二进制数据类型。所以我不明白你为什么在已经是** **日期时间的列上使用'CONVERT'到'DateTime'。 'DateTime'是'DateTime'是'DateTime' - 不需要在其上做任何字符串“格式化”!请原生使用它 –

回答

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

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

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