使用SET FMTONLY在SSRS中没有动态SQL存储过程的字段

sd_*_*ula 16 sql sql-server stored-procedures reporting-services

我有以下SP在单独运行时正常工作:

USE [Orders]
GO
SET FMTONLY OFF; 

CREATE PROCEDURE [dbo].[Get_Details_by_Type]

@isArchived varchar(10),
@Type varchar(50)

AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
    declare @sqlQuery nvarchar(max)
          IF(@isArchived = 'ALL')
            BEGIN
                set @sqlQuery  = 'SELECT *  FROM [dbo].[Orders] 
              WHERE ' + @Type + ' != € 
                ORDER BY [IDNumber]'
                exec sp_executesql @sqlQuery
            END
        ELSE
            BEGIN
            set @sqlQuery  = 'SELECT * FROM [dbo].[Orders] 
          WHERE ' + @Type + ' != € AND [isArchived] = ' + @isArchived + ' ORDER BY [IDNumber]'
            exec sp_executesql @sqlQuery
        END
END
SET FMTONLY ON; 
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,当我为SSRS报告添加DataSet时,它在Fields部分中不提取任何字段/列.我猜它是由于动态SQL?

我怎么解决这个问题?

Stu*_*tLC 23


包含Dynamic Sql和Temp表的问题存储过程是SSRS和ORM生成器(如Linq2SQL和EF逆向工程工具)等向导的祸根.

这是因为在运行PROC之前的工具SET FMTONLY ON;(或最近的工具sp_describe_first_result_set),以便派生由PROC生成的结果集模式,以便可以生成ReportViewer UI的映射.但是,既没有FMTONLY ON也没有sp_describe_first_result实际执行PROC.

例如,该工具将执行以下操作:

SET FMTONLY ON;
EXEC dbo.MyProc NULL;
Run Code Online (Sandbox Code Playgroud)

一些解决方法:

  • 手动编辑RDL/RDLC文件以插入实际结果集列名称和类型.
  • 暂时删除真正的proc并将其替换为一个返回零行或多行的数据集,其中包含真实proc返回的实际数据类型和列名,运行向导,然后还原真正的proc.
  • 添加SET FMTONLY OFF;为PROC中的第一行 - 这将强制执行PROC(尽管由于工具传入null或伪参数,proc可能会失败).此外,FMTONLY正在被弃用
  • 在proc开始时,添加一个伪语句,它返回结果集的实际模式,包装在一个永远不会被执行的条件分支中.

这是最后一次黑客攻击的一个例子:

CREATE PROCEDURE [dbo].[Get_Details_by_Type]
  @isArchived varchar(10),
  @Type varchar(50)
AS
BEGIN
   -- For FMTONLY ON tools only
   IF 1 = 2
     BEGIN
       -- These are the actual column names and types returned by the real proc
       SELECT CAST('' AS NVARCHAR(20)) AS Col1, 
              CAST(0 AS DECIMAL(5,3)) AS Col2, ...
     END;
-- Rest of the actual PROC goes here
Run Code Online (Sandbox Code Playgroud)

FMTONLY ON/ sp_describe_first_result_set被虚拟条件所欺骗,并假定来自永不执行的分支的模式.

顺便说一下,为了你自己的理智,我建议你不要SELECT *在你的PROC中 - 而是明确列出从中返回的所有真实列名Orders

最后,请确保您没有SET FMTONLY ON;在proc中包含该语句(来自上面的代码!)

END - Proc
GO **
SET FMTONLY ON; ** This isn't part of the Proc!
Run Code Online (Sandbox Code Playgroud)


小智 6

如果有人仍然面临这个问题,我用 ssrs 和动态 sql 解决了一个类似的问题。

  1. 为了使 ssrs 正确映射来自 SP 的字段,
  2. 选择查询类型下的“文本”选项,
  3. 输入 SP 名称和参数,就像您从 SSMS 窗口调用它一样。 sp_YourStoredProc @Parameter1....@ParameterN
  4. 单击刷新字段按钮。
  5. 当语句运行时,字段将刷新,并且您的矩阵将被填充。

顺便说一句,我正在使用 SQL 2012

希望这可以帮助。