在 SQL 服务器中的另一个 XQuery value() 查询中使用 XQuery value() 查询的结果

Use the result of an XQuery value() query in another XQuery value() query in SQL Server

我正在尝试查询 xml 格式的 SSRS .rdl 文件。以下是 xml:

相关部分的示例
<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition">
  <DataSources>
    <DataSource Name="DataSource1">
      <DataSourceReference>DataSourceReference1</DataSourceReference>
    </DataSource>
    <DataSource Name="DataSource2">
      <DataSourceReference>DataSourceReference2</DataSourceReference>
    </DataSource>
  </DataSources>
  <DataSets>
    <DataSet Name="DataSet1">
      <Query>
        <DataSourceName>DataSource1</DataSourceName>
        <CommandText>SELECT a from b</CommandText>
      </Query>
    </DataSet>
    <DataSet Name="DataSet2">
      <Query>
        <DataSourceName>DataSource2</DataSourceName>
        <CommandText>SELECT c from d</CommandText>
      </Query>
    </DataSet>
  </DataSets>
...

这是我目前的 SQL 查询:

IF OBJECT_ID('tempdb..#catalogtemp') IS NOT NULL DROP TABLE #catalogtemp 
GO

SELECT Path, CONVERT(XML, CONVERT(VARBINARY(MAX), Content)) XmlColumn
INTO #catalogtemp
FROM Catalog WHERE Type=2;

;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition' as rdl10)

SELECT Path as ReportPath,
T1.dataset.value('./@Name','nvarchar(max)') DatasetName,
T1.dataset.value('(.//rdl10:CommandText)[1]','nvarchar(max)') as DatasetQuery,
T1.dataset.value('(.//rdl10:DataSourceName)[1]','nvarchar(max)') as DataSourceName
FROM #catalogtemp
CROSS APPLY xmlColumn.nodes('//rdl10:DataSet') T1(dataset)

对于上面的示例 xml,这将 return:

ReportPath        DatasetName   DatasetQuery      DataSourceName
/path/to/report   DataSet1      SELECT a from b   DataSource1
/path/to/report   DataSet2      SELECT c from d   DataSource2

我想要做的是添加另一列来查找 DataSource 节点的 DataSourceReference 值,其 Name 属性与节点的 DataSourceName 值相匹配DataSet。所以查询的结果将如下所示:

ReportPath        DatasetName   DatasetQuery      DataSourceName   DataSourceReference
/path/to/report   DataSet1      SELECT a from b   DataSource1      DataSourceReference1
/path/to/report   DataSet2      SELECT c from d   DataSource2      DataSourceReference2

我知道以下 XQuery 将 return DataSource 节点的 DataSourceReferenceName 属性为 'DataSource1':

T1.dataset.value('(../..//rdl10:DataSource[@Name="DataSource1"]//rdl10:DataSourceReference)[1]','nvarchar(max)')

但是如何编写查询以每次查找正确的 DataSourceName

恕我直言,因为 <DataSources> 不包含在 <DataSets> 标签内,反之亦然,您需要一个子查询:

;WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/reporting/2010/01/reportdefinition' as rdl10)

SELECT ct.Path as ReportPath,
       T1.dataset.value('./@Name','nvarchar(max)') DatasetName,
       T1.dataset.value('(.//rdl10:CommandText)[1]','nvarchar(max)') as DatasetQuery,
       T1.dataset.value('(.//rdl10:DataSourceName)[1]','nvarchar(max)') as DataSourceName
       ,t.DSR
FROM catalogtemp ct
CROSS APPLY xmlColumn.nodes('//rdl10:DataSet') T1(dataset)
JOIN (SELECT Path,
             T2.dsrc.value('(./@Name)[1]', 'nvarchar(max)') as DSName,
             T2.dsrc.value('(.//rdl10:DataSourceReference)[1]', 'nvarchar(max)') as DSR
      FROM   catalogtemp
      CROSS APPLY xmlColumn.nodes('//rdl10:DataSource') T2(dsrc)) t
ON    t.Path = ct.Path
AND   t.DSName = T1.dataset.value('(.//rdl10:DataSourceName)[1]','nvarchar(max)')
WHERE ct.Path = 'my report'
GO
ReportPath | DatasetName | DatasetQuery    | DataSourceName | DSR                 
:--------- | :---------- | :-------------- | :------------- | :-------------------
my report  | DataSet1    | SELECT a from b | DataSource1    | DataSourceReference1
my report  | DataSet2    | SELECT c from d | DataSource2    | DataSourceReference2

dbfiddle here