【问题标题】:How to get multiple tables from stored procedure in RDLC?如何从 RDLC 中的存储过程中获取多个表?
【发布时间】:2017-03-20 14:47:00
【问题描述】:

在理解 .rdlc 报告方面遇到了很多问题。

我的情况是: 我有一个带有传入参数的过程,但有多个选择结果。 当我尝试将它与数据集一起添加时,什么也没发生,但任何其他过程(结果只有一个选择)按预期工作(它出现在“可用数据集”中。

据我了解,我可以自己创建 DataSet 并以某种方式在 .rdlc 表单中发送,但我根本无法得到它(例如,在此之后我应该如何设计 .rdlc)。

现在我从存储过程中收到了 4 个包含数据的列表,我需要将它们发送到 .rdlc 中。我怎样才能做到这一点?

【问题讨论】:

  • 尝试将存储过程分成4个部分,然后将每个部分作为一个单独的数据集添加到RDLC中。

标签: sql-server stored-procedures rdlc


【解决方案1】:

默认情况下,报告向导只会获取存储过程的第一个结果集。您可以在 ASP.NET WebForms 应用程序中以编程方式生成的 .rdlc 中的存储过程中处理多个结果集,但这并不简单......至少我知道如何做到这一点的方式不是吨。以下面的 proc 为例,它返回 3 个结果集:

CREATE PROCEDURE Multipass
AS
    DECLARE @t table (ID int, SomeText varchar(256));
    SELECT ID AS FirstID, SomeText AS FirstName FROM @t;
    SELECT ID AS SecondID, SomeText AS SecondName FROM @t;
    SELECT ID AS ThirdID, SomeText AS ThirdName FROM @t;
    RETURN 0;

现在您必须手动将数据集添加到报告文件中。创建一个空白报表项并在文本编辑器中打开(在 Visual Studio 中,您可以右键单击 .rdlc 文件,单击打开方式...并选择 Xml 编辑器以获得漂亮的颜色。)带有数据集的 .rdlc 的完整 XML对于上面添加的存储过程,看起来像这样:

<?xml version="1.0" encoding="utf-8"?>
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
  <Width>6.5in</Width>
  <Body>
    <Height>2in</Height>
  </Body>
  <rd:ReportTemplate>true</rd:ReportTemplate>
  <Page>
  </Page>
  <DataSources>
    <DataSource Name="Whatever">
      <DataSourceReference>Whatever</DataSourceReference>
      <rd:DataSourceID>b257dc38-aff2-4fac-9e8b-73ea232f5ca8</rd:DataSourceID>
    </DataSource>
  </DataSources>
  <DataSets>
    <DataSet Name="DataSet0">
      <Fields>
        <Field Name="FirstID">
          <DataField>FirstID</DataField>
          <rd:TypeName>System.int</rd:TypeName>
        </Field>
        <Field Name="FirstName">
          <DataField>FirstName</DataField>
          <rd:TypeName>System.string</rd:TypeName>
        </Field>
      </Fields>
      <Query>
        <DataSourceName>Whatever</DataSourceName>
        <CommandType>StoredProcedure</CommandType>
        <CommandText>dbo_multipass</CommandText>
      </Query>
    </DataSet>
    <DataSet Name="DataSet1">
      <Fields>
        <Field Name="SecondID">
          <DataField>SecondID</DataField>
          <rd:TypeName>System.int</rd:TypeName>
        </Field>
        <Field Name="SecondName">
          <DataField>SecondName</DataField>
          <rd:TypeName>System.string</rd:TypeName>
        </Field>
      </Fields>
      <Query>
        <DataSourceName>Whatever</DataSourceName>
        <CommandType>StoredProcedure</CommandType>
        <CommandText>dbo_multipass</CommandText>
      </Query>
    </DataSet>
    <DataSet Name="DataSet2">
      <Fields>
        <Field Name="ThirdID">
          <DataField>ThirdID</DataField>
          <rd:TypeName>System.int</rd:TypeName>
        </Field>
        <Field Name="ThirdName">
          <DataField>ThirdName</DataField>
          <rd:TypeName>System.string</rd:TypeName>
        </Field>
      </Fields>
      <Query>
        <DataSourceName>Whatever</DataSourceName>
        <CommandType>StoredProcedure</CommandType>
        <CommandText>Multipass</CommandText>
      </Query>
    </DataSet>
  </DataSets>
</Report>

请注意,我用数字命名每个数据集,这在使用模板生成报告的代码中很重要。执行以下操作,将遍历存储过程中的结果集集合并将它们添加到报告中以进行渲染:

private byte[] GetReport()
{
    Microsoft.Reporting.WebForms.Warning[] warnings = null;
    string[] streamids = null;
    string mimeType = null;
    string encoding = null;
    string extension = null;
    byte[] bytes = null;
    try
    {
        //  Retrieve the dataset from your stored proc which will contain a DataTable object for each resultset
        DataSet ds = this.GetMultipass();

        //  Instantiate a report object using your new spiffy template
        Microsoft.Reporting.WebForms.LocalReport rpt = new Microsoft.Reporting.WebForms.LocalReport();
        rpt.ReportPath = "path_to_your_report.rdlc";
        rpt.DataSources.Clear();

        //  Now we loop through the tables and add them as ReportDataSource objects to the LocalReport object
        for (int i = 0; i <= ds.Tables.Count - 1; i++)
        {
            //  Note that we name each datasource DataSet0, DataSet1, DataSet2 to match the DataSet names in the .rdlc. Kinda important.
            rpt.DataSources.Add(new Microsoft.Reporting.WebForms.ReportDataSource($"DataSet{(i > 0 ? i.ToString() : "")}", ds.Tables[i]));
        }

        // Adjust the render to how you want the output
        bytes = rpt.Render("EXCELOPENXML", null, out mimeType, out encoding, out extension, out streamids, out warnings);
    }
    catch (Exception ex)
    {
        //  Blame the internet for misguiding you
    }
    return bytes;
}

可能有更好的方法来做到这一点,希望有一种方法可以在没有 WebForms 的情况下做到这一点,否则当我最终将我的应用程序迁移到 MVC 时我遇到了麻烦。无论如何,我希望这有助于指导您朝着功能方向发展!

【讨论】:

    猜你喜欢
    • 2013-05-27
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2018-03-04
    • 2014-03-08
    • 1970-01-01
    相关资源
    最近更新 更多