SQL Server 如何通过SQL语句定位SSRS中的具体报表
在一些IT技术人员的推广、简单培训后,公司很多部门都有一些非IT技术人员参与开发各自需求的Reporting Service报表。原因很简单,罗列出来的原因大概有这样一些:
IT部门的考量:
1:IT部门这边工作量很大,跟进各个项目都力不从心。不想腾出精力和时间来解决各个部门层出不穷的报表需求。
2:IT技术人员可能对各个部门的业务的理解和那些精通业务的员工有一定的差距。业务人员才是真正懂得应用需求的核心人员。
3:这些报表的需求变跟和后续维护实在是一个不小的工作量。IT的人手、资源实在有些不足。
4:这些零零散散的报表体现不了工作量,体现不了绩效。原因你懂的。
………………………………………………………………………………
业务部门考量:
1:公司各个部门确实需要各类报表,跟进生产进度、调整生产计划,作出相关决策。这个需求的的确确是刚性需求。而且有利于提高生效效率。
2:业务人员虽然精通业务,仅仅熟悉制作Excel报表。对IT技术不了解,但是经过培训、推广后,发现Reporting Service的报表确实开发简单、而且图文并茂,美观大方。最重要的是可以重复使用,而且可以订阅、推送,大大节省了他们制作报表的时间和工作量。所以学习制作报表的热情和激情高涨
3:他们提出的需求不能得到IT部门的快速响应。有时候一拖就是一天或者几天。而需求总是在变化,他们迫切希望自己掌控这些变化。
…………………………………………………………………………………………………………………………….
结果他们“郎有情妾有意”一拍即合,结果给我整出无数的琐碎事情:一来很多人申请Reporting Service的相关权限,很多人发布更新报表。事情倒不复杂,只是琐碎繁杂,烦不胜烦,只能将一些权限下放。这个问题解决了,但是随之而来的一个更大的问题,那些没有经过专业培训的业务人员写出的SQL实在是让人大跌眼镜。有时候严重影响数据库性能。我们通过监控工具能定位到是那个Reporting Service报表发出的问题SQL,但是要如何定位到具体的报表,这样才能找到报表的Owner,督促其修改、优化SQL。否则即使我们定位了问题SQL以及知道如何优化,但是不能修改对应的报表,也只能看着问题重演。如果只是简单的将SQL发给这么一大批人,让他们自己去甄别,刷选,这个沟通的成本太高,而且效率低下,效果非常差。
搜索了一些关于Reporting Service中报表的资料,我们知道Reporting Service报表的内容都保存在ReportServer这个数据库的dbo.Catalog表中,但是官方没有关于Catalog这些系统表的相关文档。仅仅是一些对SSRS感兴趣的人做了一些深入研究,相关资料如下
关于Type字段的值代表的意义:
1 = Folder
2 = Report
3 = Resources
4 = Linked Report
5 = Data Source
6 = Report Model
7 = Report Part (SQL 2008 R2, unverified)
8 = Shared Dataset (SQL 2008 R2)
报表的XML信息保存在Catalog的Content字段中,但是Content的数据类型为Image(这个相当纳闷,不清楚为什么是这样一个设计?),如下所示,我们可以做一个转换
我们在转换成XML的文本中就能找到对应的SQL,节点一般为为/Report/DataSets/DataSet/Query/CommandText如下截图所示:
将报表内容转换为XML后,需要从XML中模糊搜索才能定位SQL出自那张报表,如下所示
WITH ItemContentBinaries AS
(
SELECT ItemID ,
Name ,
[Type] ,
CASE Type
WHEN 2 THEN 'Report'
WHEN 5 THEN 'Data Source'
WHEN 7 THEN 'Report Part'
WHEN 8 THEN 'Shared Dataset'
ELSE 'Other'
END AS TypeDescription ,
CONVERT(VARBINARY(MAX), Content) AS Content
FROM ReportServer.dbo.Catalog
WHERE Type IN ( 2, 5, 7, 8 )
),
ItemContentNoBOM AS
(
SELECT ItemID ,
Name ,
[Type] ,
TypeDescription ,
CASE WHEN LEFT(Content, 3) = 0xEFBBBF
THEN CONVERT(VARBINARY(MAX), SUBSTRING(Content, 4,
LEN(Content)))
ELSE Content
END AS Content
FROM ItemContentBinaries
)
,ItemContentXML AS
(
SELECT
ItemID,Name,[Type],TypeDescription
,CONVERT(xml,Content) AS ContentXML
FROM ItemContentNoBOM
)
SELECT
ItemID,Name,[Type],TypeDescription,ContentXML
,ISNULL(Query.value('(./*:CommandType/text())[1]','nvarchar(1024)'),'Query') AS CommandType
,Query.value('(./*:CommandText/text())[1]','nvarchar(max)') AS CommandText
FROM ItemContentXML
CROSS APPLY ItemContentXML.ContentXML.nodes('//*:Query') Queries(Query)
WHERE Query.value('(./*:CommandText/text())[1]','nvarchar(max)') LIKE '%SQL Script Content%';
不过这个SQL的性能实在慢的让人抓狂。如果有多个SQL需要定位,实在是一件折磨人的事情,我们可以将上面结果放入一张中间表或全局临时表,然后就可以快速、反复的定位SQL来自那种报表了。
WITH ItemContentBinaries AS
(
SELECT ItemID ,
Name ,
[Type] ,
CASE Type
WHEN 2 THEN 'Report'
WHEN 5 THEN 'Data Source'
WHEN 7 THEN 'Report Part'
WHEN 8 THEN 'Shared Dataset'
ELSE 'Other'
END AS TypeDescription ,
CONVERT(VARBINARY(MAX), Content) AS Content
FROM ReportServer.dbo.Catalog
WHERE Type IN ( 2, 5, 7, 8 )
),
ItemContentNoBOM AS
(
SELECT ItemID ,
Name ,
[Type] ,
TypeDescription ,
CASE WHEN LEFT(Content, 3) = 0xEFBBBF
THEN CONVERT(VARBINARY(MAX), SUBSTRING(Content, 4,
LEN(Content)))
ELSE Content
END AS Content
FROM ItemContentBinaries
)
,ItemContentXML AS
(
SELECT
ItemID,Name,[Type],TypeDescription
,CONVERT(xml,Content) AS ContentXML
FROM ItemContentNoBOM
)
SELECT
ItemID,Name,[Type],TypeDescription,ContentXML
,ISNULL(Query.value('(./*:CommandType/text())[1]','nvarchar(1024)'),'Query') AS CommandType
,Query.value('(./*:CommandText/text())[1]','nvarchar(max)') AS CommandText
INTO ##ReportContent
FROM ItemContentXML
CROSS APPLY ItemContentXML.ContentXML.nodes('//*:Query') Queries(Query);
SELECT * FROM ##ReportContent
WHERE CommandText LIKE '%使用报表的部分SQL来替换%'
如下样例所示,已经知道报表的名字,以及报表ItemID,如果你想知道报表的详细路径,通过ItemID查询ReportServer.dbo.Catalog即可得到你想要的路径信息。

参考资料:
http://bretstateham.com/extracting-ssrs-report-rdl-xml-from-the-reportserver-database/
SQL Server 如何通过SQL语句定位SSRS中的具体报表的更多相关文章
- PowerDesigner反向数据库时遇到[Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句。SQLSTATE = 37错误解决方法
逆向工程中,有时会出现如下错误 ... [Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句 SQLSTATE = 37000 解决方案: 1. ...
- SQL SERVER如何通过SQL语句获服务器硬件和系统信息
在SQL SERVER中如何通过SQL语句获取服务器硬件和系统信息呢?下面介绍一下如何通过SQL语句获取处理器(CPU).内存(Memory).磁盘(Disk)以及操作系统相关信息.如有不足和遗漏,敬 ...
- SQL Server Profiler监控执行语句
SQL Server Profiler监控执行语句,这个功能主要用在实时的监控对数据库执行了什么操作,从而及时有效的跟踪系统的运行. 常规配置选项,名称.模板.保存到文件(可以复用). 事件选择,可以 ...
- SQL Server 定时执行SQL语句的方法
SQL SERVER 定时任务,你可以启动一下.不过要想更加直观的控制,直接写一个程序,定时执行你的存储过程. 1.设置“SQL Server 代理”(SQL Server Agent)服务随系统启动 ...
- SQL Server FOR XML PATH 语句的应用---列转行
经常在论坛看到高手使用了 for xml path,由于是搜索一下,记录了详细的使用方法.在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应用 ...
- 【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句
原文:[SQL Server DBA]维护语句:删除并创建外键约束.获取建表语句 1.删除外键约束,建立外键约束 先建立3个表: /* drop table tb drop table tb_b dr ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第1部分)
为了缩小读取操作所涉及范围,本文首先着眼于简单的SELECT查询,然后引入执行更新操作有关的附加过程.最后你会读到,优化性能时SQLServer使用还原工具的相关术语和流程. 关系和存储引擎 如图所示 ...
- SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第2部分)
计划缓存(Plan Cache) 如果SQL Server已经找到一个好的方式去执行一段代码时,应该把它作为随后的请求重用,因为生成执行计划是耗费时间且资源密集的,这样做是有有意义的. 如果没找到被缓 ...
随机推荐
- ABP源码分析三十:ABP.RedisCache
ABP 通过StackExchange.Redis类库来操作Redis数据库. AbpRedisCacheModule:完成ABP.RedisCache模块的初始化(完成常规的依赖注入) AbpRed ...
- [转载]:STM32为什么必须先配置时钟再配置GPIO
转载来源 :http://blog.csdn.net/fushiqianxun/article/details/7926442 [原创]:我来添两句,就是很多同学(包括我)之前搞低端单片机,到了stm ...
- CentOS 6.8 安装TigerVNC 实现 Linux 远程桌面
CentOS 6.8 有默认的安装的 vnc 位于端口 5900 : 系统->首选项->远程桌面 勾选[共享]的选项, 取消勾选[安全]的选项, 然后防火墙添加 5900 端口 基本就可 ...
- vue源码解析阅读列表
https://zhuanlan.zhihu.com/p/24435564 开发vue(或类似的MVVM框架)的过程中,需要面对的主要问题有哪些? 剖析vue实现原理,自己动手实现mvvm 官网介绍
- 阿里云服务器的坑=====部署EF+MVC
异常处理汇总 ~ 修正果带着你的Net飞奔吧!http://www.cnblogs.com/dunitian/p/4599258.html 先参考:http://www.cnblogs.com/dun ...
- 【.NET深呼吸】如何反序列化动态JSON
.net本身除了支持SOAP.XML.二进制等序列化和反序列化,后来也加入了对JSON的序列化的支持.然而,在实际开发中,常常会遇到结构不确定的JSON对象,这些对象可能是其他代码动态生成的,你事先无 ...
- Git(进击学习:远程仓库操作)-V3.0
1.查看当前的远程仓库:git remote或git remote -v 2.添加远程仓库:git remote add [shortname] [url] git remote add pb git ...
- MUI开发APP,scroll组件,运用到区域滚动
最近在开发APP的过程中,遇到一个问题,就是内容有一个固定的头部和底部. 头部就是我们常用的header了,底部的话,就放置一个button,用来提交页面数据或者进入下一个页面等,效果 ...
- 学习Spring——依赖注入
前言: 又开始动笔开了“学习Spring”系列的头…… 其实一开始写“学习SpringMVC”的几篇文章是出于想系统的了解下Spring以及SpringMVC,因为平时在公司中虽然每天都在使用Spri ...
- IDEA上安装和使用checkstyle,findbugs,visualVM,PMD插件
##安装插件步骤: 1.打开settings 2.选择plugins 3.点击"Browse repositories" 4.搜索对应内插件,点击"install&quo ...


