【问题标题】:Use the result of an XQuery value() query in another XQuery value() query in SQL Server在 SQL Server 中的另一个 XQuery value() 查询中使用 XQuery value() 查询的结果
【发布时间】:2018-03-23 15:48:41
【问题描述】:

我正在尝试查询 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,这将返回:

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 属性与DataSetDataSourceName 值匹配。所以查询的结果应该是这样的:

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 将为 DataSource 节点返回 DataSourceReference 值,该节点的 Name 属性为“DataSource1”:

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

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

【问题讨论】:

    标签: sql-server reporting-services xquery sql-server-2014 xquery-sql


    【解决方案1】:

    恕我直言,因为&lt;DataSources&gt; 不包含在&lt;DataSets&gt; 标签中,反之亦然,您需要一个子查询:

    ;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
    
    报告路径 |数据集名称 |数据集查询 |数据源名称 | DSR :--------- | :------------ | :---------------- | :------------- | :-------------------- 我的报告 |数据集1 |从 b 中选择 a |数据源1 |数据源参考1 我的报告 |数据集2 |从 d 中选择 c |数据源2 |数据源参考2

    dbfiddle here

    【讨论】:

    • 这行得通,谢谢。我需要做的一件事是在子查询中添加一个Path 列,并将子查询加入到PathDSName 上的catalogtemp。
    • @jhnpckr 这样? dbfiddle.uk/…
    猜你喜欢
    • 1970-01-01
    • 2011-08-31
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多