T-SQL 从 RDL 数据中选择所有 XML 节点作为行
Posted
技术标签:
【中文标题】T-SQL 从 RDL 数据中选择所有 XML 节点作为行【英文标题】:T-SQL select all XML nodes as rows from RDL data 【发布时间】:2011-08-10 03:03:05 【问题描述】:我正在尝试从包含 XML 列的表中进行选择。我想获取特定节点并为每个节点创建一行。
XML 直接从 Reporting Services 数据库中获取,包含 RDL(报告)结构。我的目标是显示每个报告的所有 ‹Textbox›‹Value›example‹/Value›‹/Textbox›
值。 ‹Textbox›
节点的位置是不可预测的(它可以是 XML 结构中某处任何元素的一部分)。
以下是当前代码,但由于某种原因 id 不起作用:
IF object_id('tempdb..#c') IS NOT NULL
DROP TABLE #c
select top 50
path as reportpath
,name as reportname
,convert(xml, convert(varbinary(max), content)) as reportxml
into
#c
from
reportserver.dbo.catalog
where
content is not null
order by creationdate desc
-----------------------------------------
DECLARE @x XML
SELECT @x =
( SELECT
[reportpath]
,[reportname]
,[reportxml].query('
for $a in //../Textbox
return ‹Textbox
valueX="$a/Value"
/›
')
FROM #c AS reports
FOR XML AUTO
)
select @x
-----------------------------------------
SELECT [reportpath] = T.Item.value('../@reportpath', 'nvarchar(max)'),
[reportname] = T.Item.value('../@reportname', 'nvarchar(max)'),
value = T.Item.value('@value' , 'nvarchar(max)')
FROM @x.nodes('//reports/Textbox') AS T(Item)
下面的示例显示了包含“值”的示例“文本框”:
‹RowGrouping›
‹Width›2.53968cm‹/Width›
‹DynamicRows›
‹Grouping Name="matrix1_OperationalWeek2"›
‹GroupExpressions›
‹GroupExpression›=Fields!OperationalWeek.Value‹/GroupExpression›
‹/GroupExpressions›
‹/Grouping›
‹ReportItems›
‹Textbox Name="textbox35"›
‹rd:DefaultName›textbox35‹/rd:DefaultName›
‹Style›
‹BackgroundColor›White‹/BackgroundColor›
‹PaddingLeft›2pt‹/PaddingLeft›
‹PaddingRight›2pt‹/PaddingRight›
‹PaddingTop›2pt‹/PaddingTop›
‹PaddingBottom›2pt‹/PaddingBottom›
‹/Style›
‹ZIndex›8‹/ZIndex›
‹Value›=Fields!OperationalWeek.Value‹/Value›
‹/Textbox›
‹/ReportItems›
‹/DynamicRows›
‹/RowGrouping›
PS 我在 *** 代码格式方面遇到了一些问题,所以我用 ‹ 和 › 替换了 标记。对于那个很抱歉。
【问题讨论】:
【参考方案1】:基于 Bret 的博客 ([http://blogs.netconnex.com/2011/05/extracting-s-s-rs-report-rdl-xml-from.html][1]) 并添加命名空间会给你带来结果......我希望我可以声称我理解得足以解释,但我主要是通过“绊倒”它来找到我的方式。
--============================================== ===
;WITH XMLNAMESPACES (
DEFAULT 'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition',
'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS rd --ReportDefinition
)
select top 50
c.Path as reportpath
--, c.name as reportname
,t.value('@Name','VARCHAR(100)') as TextboxName
,t.value('data(Paragraphs/Paragraph/TextRuns/TextRun/Value)[1]', 'varchar(max)') as value
from
reportserver.dbo.catalog c
cross apply
(select convert(xml, convert(varbinary(max), content))) as R(reportxml)
cross apply
--Get all the Query elements (The "*:" ignores any xml namespaces)
r.reportxml.nodes('//*:Textbox') n(t)
where
content is not null
and c.Type = 2 -- Reports
order by creationdate desc
【讨论】:
【参考方案2】:这个简单的 XQuery:
for $a in //Textbox
return
<Textbox
valueX="$a/Value"
/>
应用于提供的 XML 文档时(添加命名空间定义以使其格式正确):
<RowGrouping xmlns:rd="rd">
<Width>2.53968cm</Width>
<DynamicRows>
<Grouping Name="matrix1_OperationalWeek2">
<GroupExpressions>
<GroupExpression>=Fields!OperationalWeek.Value</GroupExpression>
</GroupExpressions>
</Grouping>
<ReportItems>
<Textbox Name="textbox35">
<rd:DefaultName>textbox35</rd:DefaultName>
<Style>
<BackgroundColor>White</BackgroundColor>
<PaddingLeft>2pt</PaddingLeft>
<PaddingRight>2pt</PaddingRight>
<PaddingTop>2pt</PaddingTop>
<PaddingBottom>2pt</PaddingBottom>
</Style>
<ZIndex>8</ZIndex>
<Value>=Fields!OperationalWeek.Value</Value>
</Textbox>
</ReportItems>
</DynamicRows>
</RowGrouping>
产生想要的正确结果:
<?xml version="1.0" encoding="UTF-8"?>
<Textbox valueX="=Fields!OperationalWeek.Value"/>
因此,如果您无法获得结果,那么您的问题出在其他问题上,而不是在 XQuery 代码中。
【讨论】:
谢谢。不幸的是,我仍然无法找到错误。我的代码不返回任何“文本框”信息。也许它与编码有关,我还不确定如何解决这个问题......【参考方案3】:我无法测试这是否有效,但它应该可以满足您的需求。
select top 50
path as reportpath
,name as reportname
,n.t.value('Value[1]', 'varchar(max)') as value
from
reportserver.dbo.catalog
cross apply
(select convert(xml, convert(varbinary(max), content))) as c(reportxml)
cross apply
c.reportxml.nodes('//Textbox') n(t)
where
content is not null
order by creationdate desc
【讨论】:
不幸的是它返回 0 行。也许是某种转换问题或与 XML 结构有关的问题……我仍在努力寻找解决方案以上是关于T-SQL 从 RDL 数据中选择所有 XML 节点作为行的主要内容,如果未能解决你的问题,请参考以下文章
如何在 VS2003 中突出显示 rdl 项目的 xml 视图?