[SSRS]透过 SSIS 来整批导出所有 SSRS 内的报表档
既前一篇“SSRS 从 SQL Server 2008 移转并升级到 SQL Server 2014”写完之后,有朋友来信询问说,因为旧的报表项目没有保留下来,因此要整批将报表格式文件给导出,以利后续编辑或版本控制的话,那么又该怎么来处理呢 ?
网络上有介绍一些方式,像是利用 PowerShell 或者是用 T-SQL 读取 ReportServer 数据库内的 Catalog 表来处理,虽然都不错,但都有些不满意的地方,因此我用 SSIS 来展示如何实践这样的功能,基本上我会采用 VS 2013 来配合 SQL Server 2014 进行,但如果您是采用 SQL Server 2008 或 2012,基本上都是相通的。
前置处理
首先我们先建立一个 SSIS 的项目,如果您也想使用 VS 2013 的话,可以参考另外一篇文章“使用 Visual Studio Community 2013 搭配 Business Intelligence for Visual Studio 2013 开发商业智慧”,搭配社群版本的 VS 2013 来使用。
在这个项目内,一开始我们透过设定“封装参数”,设定一个参数 RootDirectory,型态是 String,主要是用来指定我们要导出的目录在哪里,如果是 SSIS 2008 的话,因为使用封装部属模式,还没有参数的功能,可以使用变量来做取代。
接着我们在“连接管理员”上新增一个新的 “ADO.Net 连线”,指定到我们所要导出的 ReportServer 的数据库上,此部分可以按照您的需要改成不同的主机或连线方式,只要能连接到 ReportServer 的数据库就可以了。
并且将该连线命名为 ReportServer
控制流程
完成前置作业之后,我们就可以先处理控制流程
1. 删除目录 : 此部分我们使用“文件系统工作”的组件,主要是用来将要导出的目录下确定没有任何旧的数据,设定参数如下:
Operation → 删除目录
IsSourcePathVariable → True
SourceVariable → $Package::RootDirectory ( 如果您是使用变量的话,则要注意一下命名空间 )
2. 取得目录 : 此部分我们使用“执行 SQL 工作”的组件,主要是用来取得导出的目录下要有那些子目录,设定参数如下:
ConnectionType → ADO.NET
Connection → ReportServer
SourceStatement → SELECT Name FROM dbo.Catalog WHERE Type = 1 AND ParentID IS NOT NULL
ResultSet → 完整结果集
因为要将结果先放到一个变量内,以利后续 Foreach 循环来使用,因此设定完“一般”的部分之后,选择左边的“结果集”,在变量的部分选择“新增变量”,加入一个新的名称是 Paths 类型为 Object 的变量
将结果放置到这个新增出来的变量内
3. Foreach 循环容器 : 此部分我们使用“Foreach 循环容器”的容器,主要是用来将上个步骤的 Paths 的变量一笔一笔取出,选择左边“集合”设定参数如下:
Enumerator → Foreach ADO 枚举值
ADO 对象来源变量 → User::Paths
为了取得循环的变量值,因此在“变量对应”的部分新增一个名称为 Path 数值类型 String 的变量
4. 取得完整目录名称 : 此部分我们使用“运算式工作”的组件,主要是用来将透过循环取得的变量值和封装参数做个合并,这样我们就可以知道在我们所要导出的目录下要建立那些目录。在执行这个步骤之前,我们需要先建立一个名称为 Directory 数值类型 String 的变量,建立好之后就可以在下方“运算式”内进行设定,要稍微注意一下因为 是跳脱符,因此这里要用两个 的符号。
运算式 → @[User::Directory] = @[$Package::RootDirectory] + "\" + @[User::Path]
5. 建立目录 : 此部分我们使用“文件系统工作”的组件,主要是用来建立导出的目录和其下的子目路,设定参数如下:
Operation → 建立目录
IsSourcePathVariable → True
SourceVariable → $User::Directory
6. 导出 XML : 此部分我们使用“数据流程工作”的组件。
数据流程
透过前面控制流程的相关处理,我们可以透过取得 Catalog 内的资讯,建立好相关的目录,接下来我们就进入数据流程,取得 Catalog 数据表内的数据并且导出 XML 的数据放置到文件内。
1. 取得 Catalog : 此部分我们使用“ADO.Net 来源”的组件,设定连接管理员和 SQL 命令文字, SQL 命令如下
WITH ItemContentBinaries AS
(
SELECT
ItemID,[Path],[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
,Content
FROM ReportServer.dbo.Catalog
WHERE Type IN (2,5,7,8)
),
ItemContent AS
(
SELECT
ItemID,[Path],[Type],TypeDescription
,CASE Type
WHEN 2 THEN '.rdl' --Report Definition Language
WHEN 5 THEN '.rds' --Report Data Source
WHEN 7 THEN '.rsc' --Report Server Component (? - Guessing)
WHEN 8 THEN '.rsd' --Report Server Data (? - Guessing)
END AS ExportFileExtension
,Content
FROM ItemContentBinaries
)
--The outer query gets the content in its varbinary, varchar and xml representations...
SELECT
REPLACE( [Path], '/', '' ) + ExportFileExtension AS ExportFileName
,Content AS ContentXML
FROM ItemContent
这样我们就可以取得导出的名称和数据内容
2. 配置文件案完整名称 : 此部分我们使用“衍生的数据行”的组件,主要是因为透过 Catalog 取得的只有相对目录的名称,因为透过衍生数据行产生出一个新的字段,该字段是我们的参数加上相对目录的名称,组出完整的文件名称。
3. 导出数据 : 此部分我们使用其他转换的“导出数据行”的组件,将字段内的数据导出。
进行测试
基本上因为这个多半是一次性的行为,因此可以直接在 VS 2013 上直接执行就可以,基本上大部分都是可以正常导出,也可以将这些数据集和报表格式导入到 VS 内的报表项目
但比较要注意的是,数据来源虽然可以导出来,但导出的格式和真正数据来源的 XML 会有所不同
导出的格式档
真正的格式档
因此如果真的要实践这个部分的话,这个部分要注意一下。
参考数据
1. How to Download All Your SSRS Report Definitions (RDL files) Using PowerShell
2. SQL Server Reporting Services (SSRS) Catalog Queries
原文:大专栏 [SSIS][SSRS]透过 SSIS 来整批导出所有 SSRS 内的报表档