动态查询和使用变量

时间:2018-02-10 14:55:16

标签: sql sql-server sql-server-2008

如果2个日期是硬编码的,则下面的查询有效,但是,我想用2个变量@FirstDayM和@LastDayM替换它们。 当我这样做时,它会返回以下错误

"从字符串"

转换日期和/或时间时转换失败
DECLARE @sql varchar(max)
DECLARE @FirstDayM DATE = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0)
DECLARE @LastDayM DATE = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1);

    SELECT @sql = Coalesce(@sql + ' UNION ALL ', '') + 'SELECT COUNT(C1CustID) AS CertsCount, ''' + QuoteName(name)+  ''' as DBname FROM ' + QuoteName(name) + '.dbo.T_C1CustCourse'+
    ' WHERE C1CertificationDate_N >= '+'''2018-01-01'''+' AND C1CertificationDate_N <= '+'''2018-01-31'''
    FROM   sys.databases WHERE database_id > 4 AND state = 0;

EXEC (@sql);

1 个答案:

答案 0 :(得分:2)

使用sp_executesql。总是。它可以轻松地将参数放入查询中。即使动态查询不是以参数开头,您也可能决定稍后再添加一个。

declare @sql nvarchar(max);
declare @firstDayM date;
declare @lastDayM date;

set @firstDayM = ?;
set @lastDayM = ?;

SELECT @sql = Coalesce(@sql + ' UNION ALL ', '') + '
SELECT COUNT(C1CustID) AS CertsCount, ''' + QuoteName(name)+  ''' as 
DBname
FROM ' + QuoteName(name) + '.dbo.T_C1CustCourse' + '
WHERE C1CertificationDate_N >= @FirstDayM AND C1CertificationDate_N 
<= @LastDayM'
FROM sys.databases
WHERE database_id > 4 AND state = 0;

EXEC sp_executesql @sql, N'@FirstDayM date, @lastDayM date',
     @FirstDayM=@FirstDayM, @lastDayM=@lastDayM;