如何批量更新SSRS报表XML中所有ReportParameter的Hidden节点为true?
需求说明:
需要更新SSRS报表XML,确保每个ReportParameter节点都设置<Hidden>true</Hidden>,处理规则如下:
- 无
Hidden节点的ReportParameter:插入<Hidden>true</Hidden>作为最后一个子节点 - 已有
<Hidden>false</Hidden>的:修改值为true - 已有
<Hidden>true</Hidden>的:跳过
问题:使用XML.modify操作时仅能生效于首个符合条件的ReportParameter,无法批量处理所有实例。
示例RDL代码
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner"> <ReportParameters> <ReportParameter Name="FederalEmployerIdentificationKey"> <DataType>Integer</DataType> <Prompt>Federal Employer Identification</Prompt> <MultiValue>true</MultiValue> </ReportParameter> <ReportParameter Name="ThirdPartySickPayAddedToOASDIWages"> <DataType>Float</DataType> <Nullable>true</Nullable> <Prompt>3rd Party Sick Pay Added To Social Security Wages</Prompt> <Hidden>false</Hidden> </ReportParameter> <ReportParameter Name="ShortDateFormat"> <DataType>String</DataType> <Hidden>true</Hidden> </ReportParameter> </ReportParameters> </Report>
尝试过的代码(仅处理首个节点)
--Replace Hidden false with Hidden true, if it is found UPDATE @xmlTable SET ContentXml.modify(' replace value of (/*:Report/*:ReportParameters/*:ReportParameter[*:Hidden="false"] /*:Hidden/text())[1] with "true" ') WHERE ContentXml.exist('/*:Report/*:ReportParameters/*:ReportParameter[*:Hidden="false"]')=1; --Insert Hidden true if no Hidden is found UPDATE @xmlTable SET ContentXml.modify(' insert (<Hidden>true</Hidden>) as last into (//*:ReportParameters/*:ReportParameter)[1] ') WHERE ContentXml.exist('(/*:Report/*:ReportParameters/*:ReportParameter/*:Hidden)')=0;
解决方案:使用循环批量处理所有节点
由于SQL Server的XML.modify()方法每次只能修改一个节点,我们可以通过循环执行修改操作,直到所有符合条件的节点都被处理完毕。
步骤1:批量修改所有<Hidden>false</Hidden>为<Hidden>true</Hidden>
WHILE EXISTS ( SELECT 1 FROM @xmlTable WHERE ContentXml.exist('/*:Report/*:ReportParameters/*:ReportParameter[*:Hidden="false"]') = 1 ) BEGIN UPDATE @xmlTable SET ContentXml.modify(' replace value of (/*:Report/*:ReportParameters/*:ReportParameter[*:Hidden="false"]/*:Hidden/text())[1] with "true" ') WHERE ContentXml.exist('/*:Report/*:ReportParameters/*:ReportParameter[*:Hidden="false"]') = 1; END
步骤2:批量为所有无Hidden节点的ReportParameter插入<Hidden>true</Hidden>
WHILE EXISTS ( SELECT 1 FROM @xmlTable WHERE ContentXml.exist('/*:Report/*:ReportParameters/*:ReportParameter[not(*:Hidden)]') = 1 ) BEGIN UPDATE @xmlTable SET ContentXml.modify(' insert <Hidden>true</Hidden> as last into (/*:Report/*:ReportParameters/*:ReportParameter[not(*:Hidden)])[1] ') WHERE ContentXml.exist('/*:Report/*:ReportParameters/*:ReportParameter[not(*:Hidden)]') = 1; END
完整逻辑说明
- 循环的终止条件是:不存在需要修改/插入的节点时,循环结束
- 每次循环中,
XML.modify()处理第一个符合条件的节点,多次循环后即可覆盖所有目标节点 - 使用
not(*:Hidden)精准定位没有Hidden子节点的ReportParameter,避免误操作已有Hidden节点的实例
内容的提问来源于stack exchange,提问作者svenGUTT
相关产品推荐
相关产品推荐

