我有一个SSRSreport,它将以下文本发送到数据库:
EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams +
' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , ' +
@DateFrom + ', ' + @DateTo + ', ' + @InputRankGroups + ', ' +
@SubCategories )
当我在profiler中查看它时,它将其解释为:
exec sp_executesql N'EXEC ( ''DECLARE @TeamIds as TeamIdTableType '' + @Teams +
'' EXEC rpt.DWTypeOfSicknessByCategoryAndEmployeeDetailsReport @TeamIds, '' +
@DateFrom + '', '' + @DateTo + '', '' + @InputRankGroups + '', '' +
@SubCategories )',
N'@Teams nvarchar(34),@DateFrom datetime,@DateTo datetime,
@InputRankGroups varchar(1),@SubCategories bit',
@Teams=N'INSERT INTO @TeamIds VALUES (5);',
@DateFrom='2010-02-01 00:00:00',@DateTo='2010-04-30 00:00:00',
@InputRankGroups=N'1',@SubCategories=1
当这个sql在日期运行时出现错误。
我尝试更改日期格式,但没有帮助。如果我删除日期,它可以正常工作。
答案 0 :(得分:1)
我想我知道这里发生了什么。如果执行的SQL是
EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams
+ ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , '
+ @DateFrom + ', '
+ @DateTo + ', '
+ @InputRankGroups + ', '
+ @SubCategories )
... SQL Server将首先执行字符串连接,然后在连接字符串上调用EXEC
。使用给定参数的值,这意味着连接的字符串将类似于以下内容(为了可读性而调整了空白):
DECLARE @TeamIds as TeamIdTableType
INSERT INTO @TeamIds VALUES (5);
EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds ,
2010-02-01 00:00:00, 2010-04-30 00:00:00, 1, 1
问题是EXEC不是参数化查询,因此它必须将datetime参数解释为原始字符串,但作为原始未加引号的字符串,它们不是正确的语法。您可以通过以下两种方式解决此问题。
首先,简单方法:引用日期时间字符串。
EXEC ( 'DECLARE @TeamIds as TeamIdTableType ' + @Teams
+ ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , '
+ '''' + @DateFrom + ''', '
+ '''' + @DateTo + ''', '
+ @InputRankGroups + ', '
+ @SubCategories )
这为您提供了有效语法:
DECLARE @TeamIds as TeamIdTableType
INSERT INTO @TeamIds VALUES (5);
EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds ,
'2010-02-01 00:00:00', '2010-04-30 00:00:00', 1, 1
其次,几乎是简单但更正确的方式:使用参数化查询。
DECLARE @sql varchar(max)
SET @sql = 'DECLARE @TeamIds AS TeamIdTableType ' + @Teams
+ ' EXEC rpt.DWTypeOfSicknessByCategoryReport @TeamIds , @DateFrom, @DateTo, @InputRankGroups, @SubCategories'
EXEC sp_executesql @sql, N'@DateFrom datetime,@DateTo datetime,@InputRankGroups varchar(1),@SubCategories bit',
@DateFrom, @DateTo, @InputRankGroups, @SubCategories
这样您就不必担心如何转义特定的值类型,尽管它稍微冗长一些。请注意,由于将原始SQL作为@Teams中的参数传递,因此无法完全对其进行参数化。这可能不是你可以控制的东西 - 我对SSRS并不熟悉。
答案 1 :(得分:0)
感谢您分享您的解决方案。我试图实现第二个,但我收到一个错误调用存储过程。我不得不稍微调整语法,这对我有用:
DECLARE @vSQL nvarchar(max) = N'
DECLARE @customerIdList Report.IntegerListTableType;
'+@customerIdInserts+';
EXEC rpt_CustomerTransactionSummary
@startDate=@startDate,
@endDate=@endDate,
@accountType=@accountType,
@customerIds = @customerIdList';
exec sp_executesql
@vSQL,
N'@startDate datetime, @endDate datetime, @accountType int',
@startDate,
@endDate',
@accountType;
此语法也允许NULL值(例如,@ accountType = NULL)