在一些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即可得到你想要的路径信息。

 

参考资料:

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/60dd3392-42d8-4dc4-b8e6-15e9aeaad29e/table-explaination-for-dbocatalog-table-in-reportserver-database?forum=sqlreportingservices

http://bretstateham.com/extracting-ssrs-report-rdl-xml-from-the-reportserver-database/

SQL Server 如何通过SQL语句定位SSRS中的具体报表的更多相关文章

  1. PowerDesigner反向数据库时遇到[Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句。SQLSTATE = 37错误解决方法

    逆向工程中,有时会出现如下错误 ... [Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句 SQLSTATE = 37000 解决方案: 1. ...

  2. SQL SERVER如何通过SQL语句获服务器硬件和系统信息

    在SQL SERVER中如何通过SQL语句获取服务器硬件和系统信息呢?下面介绍一下如何通过SQL语句获取处理器(CPU).内存(Memory).磁盘(Disk)以及操作系统相关信息.如有不足和遗漏,敬 ...

  3. SQL Server Profiler监控执行语句

    SQL Server Profiler监控执行语句,这个功能主要用在实时的监控对数据库执行了什么操作,从而及时有效的跟踪系统的运行. 常规配置选项,名称.模板.保存到文件(可以复用). 事件选择,可以 ...

  4. SQL Server 定时执行SQL语句的方法

    SQL SERVER 定时任务,你可以启动一下.不过要想更加直观的控制,直接写一个程序,定时执行你的存储过程. 1.设置“SQL Server 代理”(SQL Server Agent)服务随系统启动 ...

  5. SQL Server FOR XML PATH 语句的应用---列转行

    经常在论坛看到高手使用了 for xml path,由于是搜索一下,记录了详细的使用方法.在SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,下面是它的一些应用 ...

  6. 【SQL Server DBA】维护语句:删除并创建外键约束、获取建表语句

    原文:[SQL Server DBA]维护语句:删除并创建外键约束.获取建表语句 1.删除外键约束,建立外键约束 先建立3个表: /* drop table tb drop table tb_b dr ...

  7. c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程

    c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...

  8. SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第1部分)

    为了缩小读取操作所涉及范围,本文首先着眼于简单的SELECT查询,然后引入执行更新操作有关的附加过程.最后你会读到,优化性能时SQLServer使用还原工具的相关术语和流程. 关系和存储引擎 如图所示 ...

  9. SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第2部分)

    计划缓存(Plan Cache) 如果SQL Server已经找到一个好的方式去执行一段代码时,应该把它作为随后的请求重用,因为生成执行计划是耗费时间且资源密集的,这样做是有有意义的. 如果没找到被缓 ...

随机推荐

  1. 2000条你应知的WPF小姿势 基础篇<22-27 WPF生命周期, 基础类等>

    端午长假在家陪着女朋友, 幸福感满满,生活对于一只饱经忧患的程序猿来说也是非常重要的,也就暂时没有更新博客.休假结束,回归奋斗的日子了,开始继续更新WPF系列. 在正文开始之前需要介绍一个人:Sean ...

  2. JavaScript的基准测试-不服跑个分?

    原文:Bulletproof JavaScript benchmarks 做JavaScript的基准测试并没有想的那么简单.即使不考虑浏览器差异所带来的影响,也有很多难点-或者说陷阱需要面对. 这是 ...

  3. python scikit-learn 环境搭建问题解决记录

    之前一直用pycharm 里内置的pip进行python 包的安装,今天装scikit-learn时没报错,但是报scipy包不识别,pip下载也报错下载anaconda 集成插件,最终问题解决:参考 ...

  4. 前端移动App开发环境搭建

    移动App开发环境安装 一.环境安装准备软件 二.node的安装 像安装普通软件一样,安装对应版本的node软件,安装好之后就可以运行npm命令行,比如npm init .npm install -g ...

  5. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  6. 利用select实现IO多路复用TCP服务端

    一.相关函数 1.  int select(int maxfdp, fd_set *readset, fd_set *writeset, fd_set *exceptset,struct timeva ...

  7. Webpack从入门到上线

    webpack是目前一个很热门的前端打包工具,官网说得很清楚,webpack的出现就是要把requirejs干掉.同时它还提供了十分便利的本地开发的环境.网上并不容易找到一个讲解得比较详细完整的教程, ...

  8. 神秘的 shadow-dom 浅析

    说到 shadow-dom 可能很多人会很陌生.但是其实我们肯定碰到过,本文主要想简单介绍下 shadow-dom.下面直接进入正文. shadow-dom 是什么 顾名思义, shadow-dom, ...

  9. DDD 领域驱动设计-如何 DDD?

    注:科比今天要退役了,我是 60 亿分之一,满腹怀念-

  10. 【分布式】Zookeeper请求处理

    一.前言 在前面学习了Zookeeper中服务器的三种角色及其之间的通信,接着学习对于客户端的一次请求,Zookeeper是如何进行处理的. 二.请求处理 2.1 会话创建请求 Zookeeper服务 ...