编写 C# 代码以创建 SSRS 数据驱动订阅

Programming c# code to create a SSRS data driven subscription

我在 SQL Reporting Service 2012 标准版下有带参数的 SSRS 报告。我喜欢导出到 excel 并作为电子邮件中的附件发送到不同的收据,而收据来自某些 SQL 查询,这意味着它是动态的。

数据驱动订阅可以做到这一点,但我有 SQL Server 2012 标准版,它不支持数据驱动订阅,我无法升级,所以我正在寻找可以执行类似操作的任何代码像数据驱动订阅一样的工作。

我发现这个 link 可以解决我的问题。 http://jaliyaudagedara.blogspot.com/2012/10/creating-data-driven-subscription.html

当我通过添加服务引用“http://mylocalserver:81/reportserver/ReportService2010.asmx”在 visual studio 2015 "Class Library" 项目下尝试此代码时,我在这行代码中遇到错误。 ReportingService2010SoapClient rs= new ReportingService2010SoapClient();

有关错误的其他信息:在 ServiceModel 客户端配置部分找不到引用合同 'ReportService2010.ReportingService2010Soap' 的默认端点元素。这可能是因为没有找到您的应用程序的配置文件,或者因为在客户端元素中找不到匹配此协定的端点元素。

在花了足够的时间使其与 "Class Library" 项目一起工作后,我决定通过添加 Web 服务引用来在 Web 服务项目下编写代码。经过反复试验,我终于在 Web 服务项目下获得了工作代码。下面的代码在我的本地机器上工作,它有 Sql 服务器 2012 企业版,但它给了我同样的错误,说 "Data-driven subscriptions to reports" 在我公司的服务器上有 SQL服务器2012标准版。

   public void DoWork()
    {
       ReportingService2010 rs = new ReportingService2010();
        rs.Credentials = CredentialCache.DefaultCredentials;
       // rs.Url = "http://mylocalserver:81/reportserver/ReportService2010.asmx";
        rs.Url = "http://companyserver/reportserver/ReportService2010.asmx";

        var reportPath = "/CYTYC Reports/";

        string report = $"{reportPath}AllContactCIPPointsReport";
        string description = "Programmatic Data Driven Subscription \"Report Server Email\" ";

        //set extension as Windows File Share
        ExtensionSettings settings = new ExtensionSettings();
        settings.Extension = "Report Server Email";


        // Set the extension parameter values.
        var extensionParams = new ParameterValueOrFieldReference[8];

        // var to = new ParameterFieldReference { ParameterName = "TO", FieldAlias = "PARAMS" }; // Data-driven.
        var to = new ParameterValue { Name = "TO", Value = "example@gmail.com" }; // Data-driven.
        extensionParams[0] = to;

        var replyTo = new ParameterValue { Name = "ReplyTo", Value = "example@gmail.com" };
        extensionParams[1] = replyTo;

        var includeReport = new ParameterValue { Name = "IncludeReport", Value = "False" };
        extensionParams[2] = includeReport;

        var renderFormat = new ParameterValue { Name = "RenderFormat", Value = "HTML4.0" };
        extensionParams[3] = renderFormat;

        var priority = new ParameterValue { Name = "Priority", Value = "NORMAL" };
        extensionParams[4] = priority;

        var subject = new ParameterValue { Name = "Subject", Value = "Subsribed Report" };
        extensionParams[5] = subject;

        var comment = new ParameterValue { Name = "Comment", Value = "Here is the link to your report." };
        extensionParams[6] = comment;

        var includeLink = new ParameterValue { Name = "IncludeLink", Value = "True" };
        extensionParams[7] = includeLink;

        settings.ParameterValues = extensionParams;

        // Create the data source for the delivery query.
        var delivery = new DataSource { Name = "" };
        var dataSourceDefinition = new DataSourceDefinition
        {
            ConnectString = "Data Source=CYTYC-LIVE;Initial Catalog=yourdatabasename",
            CredentialRetrieval = CredentialRetrievalEnum.Store,
            Enabled = true,
            EnabledSpecified = true,
            Extension = "SQL",
            ImpersonateUserSpecified = false,
            UserName = "username",
            Password = "password"
        };
        delivery.Item = dataSourceDefinition;

        // Create the data set for the delivery query.
        var dataSetDefinition = new DataSetDefinition
        {
            AccentSensitivitySpecified = false,
            CaseSensitivitySpecified = false,
            KanatypeSensitivitySpecified = false,
            WidthSensitivitySpecified = false
        };
        var queryDefinition = new QueryDefinition
        {
            CommandText = @"Your select * from Query",
            CommandType = "Text",
            Timeout = 45,
            TimeoutSpecified = true
        };
        dataSetDefinition.Query = queryDefinition;
        var results = new DataSetDefinition();
        var oServerInfoHeader = new ServerInfoHeader();
        var oTrustedUserHeader = new TrustedUserHeader();

        bool changed;
        string[] paramNames;
        try
        {
            results = rs.PrepareQuery(delivery, dataSetDefinition, out changed, out paramNames);//.PrepareQuery(oTrustedUserHeader, delivery, dataSetDefinition, out results, out changed,out paramNames);

        }
        catch (Exception ex)
        {

            Console.WriteLine(ex.Message);
        }

        var dataRetrieval = new DataRetrievalPlan { DataSet = results, Item = dataSourceDefinition };


        // Set the event type and match data for the delivery.
        const string eventType = "TimedSubscription";
        const string matchData = "<ScheduleDefinition><StartDateTime>2018-06-01T14:00:00-07:00</StartDateTime><WeeklyRecurrence><WeeksInterval>1</WeeksInterval><DaysOfWeek><Monday>True</Monday><Tuesday>True</Tuesday><Wednesday>True</Wednesday><Thursday>True</Thursday><Friday>True</Friday></DaysOfWeek></WeeklyRecurrence></ScheduleDefinition>";

        //const string eventType = "SnapshotUpdated";
        //const string matchData = null;

        //// Set the report parameter values.
        //var parameters = new ParameterValueOrFieldReference[1];

        //// i am retrieving value EMAIL from database and I am passing that value as my report parameter value
        //var reportparam = new ParameterFieldReference { ParameterName = "yourreportparametername", FieldAlias = "PARAMS" }; // Data-driven.

        //parameters[0] = reportparam;

        var parameters = new ParameterValue[1];
        var reportparam = new ParameterValue {Name = "yourreportparametername", Value = "yourreportparametervalue"};
        parameters[0] = reportparam;

        string subscriptionId = "";
        try
        {

            subscriptionId = rs.CreateDataDrivenSubscription(report, settings, dataRetrieval, description, eventType, matchData, parameters);
            //(oTrustedUserHeader, report, settings, dataRetrieval,description, eventType, matchData, parameters,out subscriptionId);
        }
        catch (System.Web.Services.Protocols.SoapException ex)
        {
            Console.WriteLine(ex.Detail.InnerText.ToString(CultureInfo.InvariantCulture));
        }

    }

您没有说明为什么需要数据驱动订阅 - 常规 SSRS 订阅可以通过电子邮件发送带有设置或默认参数的 Excel 报告。

据我所知,没有任何第三方工具可以模拟数据驱动订阅,但有些用户已经创建了自己的工具。

如果您只是想根据条件触发订阅,您可以只使用 SSIS 作业 运行 查询来确定是否发送并在发送时触发订阅。

Something like Data Driven Subscriptions SSRS Standard Edition 2008

如果您需要更复杂的东西(例如改变 TO/CC 收件人、更改参数值...),您需要进行更多的编程。以下是理论和代码入门的几件事:

https://www.mssqltips.com/sqlservertip/4249/simulate-reporting-services-data-driven-subscriptions-on-unsupported-editions/

http://www.sqlservercentral.com/articles/Reporting+Services+(SSRS)/163119/