设置多个 XMLNAMESPACES 以说明 SQL 查询中 SSRS/SQL 的不同版本
Set Multiple XMLNAMESPACES to account for different versions of SSRS/SQL in an SQL Query
我正在尝试查询 SSRS 报表服务器数据库,搜索使用 LIKE 语句使用特定存储过程的任何报表。
下面的代码完美运行:
WITH XMLNAMESPACES
( DEFAULT
'http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition'
, 'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS ReportDefinition )
SELECT
CATDATA.Name AS ReportName
,CATDATA.Path AS ReportPathLocation
,xmlcolumn.value('(@Name)[1]', 'VARCHAR(250)') AS DataSetName
,xmlcolumn.value('(Query/DataSourceName)[1]','VARCHAR(250)') AS DataSoureName
,xmlcolumn.value('(Query/CommandText)[1]','VARCHAR(2500)') AS CommandText
FROM (
SELECT C.Name
,C.Path
,CONVERT(XML,CONVERT(VARBINARY(MAX),C.Content)) AS reportXML
FROM ReportServer.dbo.Catalog C
WHERE C.Content is not null
AND C.Type = 2
) CATDATA
CROSS APPLY reportXML.nodes('/Report/DataSets/DataSet') xmltable ( xmlcolumn )
WHERE
xmlcolumn.value('(Query/CommandText)[1]','VARCHAR(500)') LIKE '%sp_%'
ORDER BY CATDATA.Name
但是我想跨多个 XML 命名空间进行查询,以说明 SSRS/SQL 版本随时间的变化,以确保查询不会遗漏任何记录。
'http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition'
'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition'
我仍然是 XML 的相对初学者,有什么想法或建议我会如何去做?
非常感谢
如果您不介意不同名称空间中的节点冲突,那么您可以完全忽略名称空间,使用 *:node
SELECT
CATDATA.Name AS ReportName
,CATDATA.Path AS ReportPathLocation
,xmlcolumn.value('(@Name)[1]', 'VARCHAR(250)') AS DataSetName
,xmlcolumn.value('(*:Query/*:DataSourceName/text())[1]','VARCHAR(250)') AS DataSoureName
,xmlcolumn.value('(*:Query/*:CommandText/text())[1]','VARCHAR(2500)') AS CommandText
FROM (
SELECT C.Name
,C.Path
,CONVERT(XML,CONVERT(VARBINARY(MAX),C.Content)) AS reportXML
FROM ReportServer.dbo.Catalog C
WHERE C.Content is not null
AND C.Type = 2
) CATDATA
CROSS APPLY reportXML.nodes('/*:Report/*:DataSets/*:DataSet') xmltable ( xmlcolumn )
WHERE
xmlcolumn.value('(*:Query/*:CommandText/text())[1]','VARCHAR(500)') LIKE '%sp_%'
ORDER BY CATDATA.Name
出于性能原因,您应该始终使用 /text()
获取节点的内部文本。
请注意,您可以将 WHERE
过滤器合并到 nodes
过滤器中,并直接在 XQuery 中进行:
CROSS APPLY reportXML.nodes(
'/*:Report/*:DataSets/*:DataSet[
*:Query[*:CommandText[
contains(text()[1], "sp_")
]]]') xmltable ( xmlcolumn )
我正在尝试查询 SSRS 报表服务器数据库,搜索使用 LIKE 语句使用特定存储过程的任何报表。
下面的代码完美运行:
WITH XMLNAMESPACES
( DEFAULT
'http://schemas.microsoft.com/sqlserver/reporting/2016/01/reportdefinition'
, 'http://schemas.microsoft.com/SQLServer/reporting/reportdesigner' AS ReportDefinition )
SELECT
CATDATA.Name AS ReportName
,CATDATA.Path AS ReportPathLocation
,xmlcolumn.value('(@Name)[1]', 'VARCHAR(250)') AS DataSetName
,xmlcolumn.value('(Query/DataSourceName)[1]','VARCHAR(250)') AS DataSoureName
,xmlcolumn.value('(Query/CommandText)[1]','VARCHAR(2500)') AS CommandText
FROM (
SELECT C.Name
,C.Path
,CONVERT(XML,CONVERT(VARBINARY(MAX),C.Content)) AS reportXML
FROM ReportServer.dbo.Catalog C
WHERE C.Content is not null
AND C.Type = 2
) CATDATA
CROSS APPLY reportXML.nodes('/Report/DataSets/DataSet') xmltable ( xmlcolumn )
WHERE
xmlcolumn.value('(Query/CommandText)[1]','VARCHAR(500)') LIKE '%sp_%'
ORDER BY CATDATA.Name
但是我想跨多个 XML 命名空间进行查询,以说明 SSRS/SQL 版本随时间的变化,以确保查询不会遗漏任何记录。
'http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition'
'http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition'
我仍然是 XML 的相对初学者,有什么想法或建议我会如何去做?
非常感谢
如果您不介意不同名称空间中的节点冲突,那么您可以完全忽略名称空间,使用 *:node
SELECT
CATDATA.Name AS ReportName
,CATDATA.Path AS ReportPathLocation
,xmlcolumn.value('(@Name)[1]', 'VARCHAR(250)') AS DataSetName
,xmlcolumn.value('(*:Query/*:DataSourceName/text())[1]','VARCHAR(250)') AS DataSoureName
,xmlcolumn.value('(*:Query/*:CommandText/text())[1]','VARCHAR(2500)') AS CommandText
FROM (
SELECT C.Name
,C.Path
,CONVERT(XML,CONVERT(VARBINARY(MAX),C.Content)) AS reportXML
FROM ReportServer.dbo.Catalog C
WHERE C.Content is not null
AND C.Type = 2
) CATDATA
CROSS APPLY reportXML.nodes('/*:Report/*:DataSets/*:DataSet') xmltable ( xmlcolumn )
WHERE
xmlcolumn.value('(*:Query/*:CommandText/text())[1]','VARCHAR(500)') LIKE '%sp_%'
ORDER BY CATDATA.Name
出于性能原因,您应该始终使用 /text()
获取节点的内部文本。
请注意,您可以将 WHERE
过滤器合并到 nodes
过滤器中,并直接在 XQuery 中进行:
CROSS APPLY reportXML.nodes(
'/*:Report/*:DataSets/*:DataSet[
*:Query[*:CommandText[
contains(text()[1], "sp_")
]]]') xmltable ( xmlcolumn )