如何在不生成订阅的情况下从ReportServer数据库运行报表



我想建立一个后端系统,允许我每晚运行每个报告,然后查询执行日志,看看是否有任何失败。我知道你可以为这些报告建立订阅并定义参数等,但有没有一种方法可以在不建立每个订阅的情况下使用TSQL从ReportServer数据库执行每个报告?

我知道您的总体目标是实现自动化,而不必为每个报告编写订阅。你说你想在T-SQL中实现它,但这是满足你的总体目标所必需的吗?

如果可以接受,例如.Net,那么可以使用System.Data.SqlClient.SqlConnection和相关类来查询报表服务器目录并获取所有报表的列表。

然后,您可以使用System.Net.WebClient或类似工具尝试下载报告的pdf。从那里,您可以读取执行日志,也可以捕获.Net代码中的错误。

编辑

好吧,既然你接受了答案,而且你似乎可以走这条路,我要说的是,如果你不熟悉.net,这对你来说可能是一条很长的路。这里有一些东西可以让你开始。

下面是一个使用.Net的c#函数,它将查询报表目录。如果safeIntermediate设置为true,它将只捕获可以立即运行的报告,因为在中没有参数或默认值包含这些参数。

IEnumerable<string> GetReportPaths(
string conStr,
bool safeImmediate // as in, you can exexute the report right away without paramters
) {
using (var con = new SqlConnection(conStr))
using (var cmd = new SqlCommand()) {
cmd.Connection = con;
cmd.CommandText = @"select path from catalog where type=2";
con.Open();
if (safeImmediate) 
cmd.CommandText = @"
select      path
from        catalog 
cross apply (select 
params = convert(xml, Parameter).value('count(Parameters/Parameter)', 'int'),
defaults = convert(xml, Parameter).value('count(Parameters/Parameter/DefaultValues/Value)', 'int')
) counts
where       type = 2  
and         params = defaults
and         path not like '%subreport%' -- this is not standard.  Just works for my conventions
";
using (var rdr = cmd.ExecuteReader())
while (rdr.Read()) 
yield return rdr["path"].ToString();
}
}

下一个功能将下载一个报告,并给出正确的路径:

byte[] DownloadReport (
WebClient wc, 
string coreUrl, 
string fullReportPath, 
string parameters = "" // you won't use this but may come in handy for other uses
) {
var pathToViewer = "ReportServer/Pages/ReportViewer.aspx"; // for typical ssrs installs
var renderOptions = "&rs:Format=pdf&rs:Command=Render"; // return as pdf
var url = $@"{coreUrl}/{pathToViewer}?{fullReportPath}{parameters}{renderOptions}";
url = Uri.EscapeUriString(url); // url's don't like certain characters, fix it
return wc.DownloadData(url); 
}

这利用上面的函数来找到成功的和不成功的:

var sqlCon = "Server=yourReportServer; Database=ReportServer; Integrated Security=yes"; // or whatever
var ssrsSite = "http://www.yourSite.org";
using (var wc = new WebClient()) {
wc.UseDefaultCredentials = true; // or whatever
int loops = 3; // get rid of this when you're ready for prime-time
foreach(var path in GetReportPaths(sqlCon, true)) {
try {
DownloadReport(wc, ssrsSite, path);
Debug.WriteLine($"Success with: {path}");
}
catch(Exception ex) { // you might want to get more specific
Debug.WriteLine($"Failed with: {path}"); 
}
if (loops-- == 0)
break;
}
}

需要学习的东西很多,但也可能非常有益。祝你好运

相关内容

最新更新