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

时间:2014-01-29 15:02:31

标签: 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; 

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

我该如何解决?

7 个答案:

答案 0 :(得分:21)

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

这是因为在运行PROC之前的工具SET FMTONLY ON;(或者最近,sp_describe_first_result_set),以便派生PROC生成的结果集架构,以便ReportViewer UI的映射可以是产生。但是,FMTONLY ONsp_describe_first_result实际上都不执行PROC。

e.g。该工具将执行以下操作:

SET FMTONLY ON;
EXEC dbo.MyProc NULL;

一些解决方法:

  • 手动编辑RDL / RDLC文件以插入实际结果集列名称和类型。
  • 暂时删除真正的proc并将其替换为一个返回零行或多行的数据集,其中包含真实proc返回的实际数据类型和列名,运行向导,然后还原真正的proc。
  • 添加SET FMTONLY OFF;作为PROC中的第一行 - 这将强制执行PROC(尽管由于工具传入null或伪参数,proc可能会失败)。此外,FMTONLYbeing deprecated
  • 在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

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

顺便说一句,为了您自己的理智,我建议您不要在PROC中SELECT * - 而是明确列出从Orders

返回的所有真实列名称

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

END - Proc
GO **
SET FMTONLY ON; ** This isn't part of the Proc!

答案 1 :(得分:4)

如果有人还在面对这个问题,我解决了与ssrs和动态sql类似的问题。

  1. 让ssrs正确映射SP中的字段
  2. 选择查询类型
  3. 下的“文字”选项
  4. 输入SP名称和参数,就像您从SSMS窗口调用它一样。 sp_YourStoredProc @Parameter1....@ParameterN
  5. 点击刷新字段按钮。
  6. 当语句运行时,字段将刷新,您的矩阵将被填充。
  7. BTW,我正在使用SQL 2012

    希望这有帮助。

答案 2 :(得分:1)

以下是我为解决此问题所做的工作 - 字段未在SSRS中列出

  1. 最初我有存储过程;并在执行数据集时返回数据。但这些字段未列在SSRS

  2. 我复制了存储过程的文本,并将数据集设为Text而不是Stored Procedure。请参阅How to: Refresh Fields for a Dataset

  3. 它产生了错误,我“忽略”了这些错误。请参阅The Declare cursor SQL construct or statement is not supported.

  4. 现在我确认已填写SSRS

  5. 字段
  6. 现在我更新了数据集以使用我的Stored Procedure

  7. 完成上述步骤后,刷新数据集,如下所示:

    enter image description here

答案 3 :(得分:0)

按照以下步骤

•   Delete DataSource. Create a new Data Source .
•   Delete DataSet. Create a new DataSet .
•   Use Query Designer. 
•   Add valid parameter when asked  .
•   One should get result for provided prarameters . 
    Donot click on refresh Field .
•   Then Report parameters and Report field will appear .
•   Now Filter criteria should work.

OR

**Add the Report field manually . It works.**

如果存储过程无法检索架构数据或元数据,我们应手动指定报告字段。

答案 4 :(得分:0)

这是一个非常晚的补充,但对于我们这些SSRS /报告设计的新手: 请记住在Visual Studio的“报表数据”窗格中检查参数的顺序。它们将从上到下创建,因此顶部的参数不能依赖于底部的参数。这是我在一份报告中遇到的问题,但我收到的错误信息没有说明,所以我追了好几个小时试图解决它。

答案 5 :(得分:0)

并不意味着重振死线,但在将我们的报告从SSRS 2005升级到存储过程使用openquery的SSRS 2016时让我发疯。

我们将其缩小为包含空值的字段的报告。所以我们在存储过程的开头添加了这个:

SET CONCAT_NULL_YIELDS_NULL OFF;

这意味着我们不需要在每个领域进行CAST。

答案 6 :(得分:0)

我遇到了类似的问题。我有一些调试语句,经常打开/关闭w /标志变量。

此行即使不运行也仍会影响结果(@debug = 0)

--check your work
if @debug =1  select @reportStartDate  RSD ,@reportEndDate 
         , @yearStart YS, @folderStartDate  FSD, @MonthCount MC
         , @dataStart  DataStart

我通过在

上运行sp w / fmtONly发现了问题
SET FMTONLY ON
exec rpt_mo_DashBoard_YTD_Total  'ajax20','12/1/2019'

我通过注释掉SP中的代码解决了这个问题。是的,现在我必须在调试时取消注释/ recomment每个return语句的时间...