我正在尝试从包含XML列的表中进行SELECT。我想获取特定节点并为每个节点创建一行。
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)
下面的示例显示了包含“值”的示例“文本框”:
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)
PS我在stackoverflow代码格式化方面遇到了一些麻烦,所以我更换了&lt;和&gt;用<和>标记。对于那个很抱歉。
答案 0 :(得分:4)
基于布雷特的博客([http://blogs.netconnex.com/2011/05/extracting-ssrs-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
答案 1 :(得分:1)
这个简单的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代码中。
答案 2 :(得分:0)
我无法测试这是否有效,但它应该做你想要的。
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