【问题标题】:XQuery and Node IdsXQuery 和节点 ID
【发布时间】:2011-06-24 19:01:14
【问题描述】:

我有这个变量:

declare @xmlDoc XML

它存储了以下xml:

<?xml version="1.0" encoding="utf-8"?>
<NewDataSet>
  <Table1>
    <Sharedparam>shared</Sharedparam>
    <Antoher>sahre</Antoher>
    <RandomParam2>Good stuff</RandomParam2>
    <MoreParam>and more</MoreParam>
    <ResultsParam>2</ResultsParam>
  </Table1>
  <Table1>       
    <RandomParam2>do you</RandomParam2>
    <MoreParam>think</MoreParam>
    <ResultsParam>2</ResultsParam>
  </Table1>
  <Table1>
    <Sharedparam>Last</Sharedparam>
    <Antoher> Set </Antoher>
    <RandomParam2> of </RandomParam2>
    <MoreParam>values</MoreParam>
    <ResultsParam>are here</ResultsParam>
  </Table1>
  <Table1 />
</NewDataSet>

我有这个用于获取数据的查询:

declare @xmlDoc XML
set @xmlDoc = '' -- Stack Overflow could not handle the xml all on one line.

SELECT   -- Param 1
         TBL.SParam.value('local-name((*)[1])', 'varchar(50)') as Param1Name,
         TBL.SParam.value('(*)[1]', 'varchar(100)') as Param1Value,             
         -- Param2
         TBL.SParam.value('local-name((*)[2])', 'varchar(50)') as Param2Name,
         TBL.SParam.value('(*)[2]', 'varchar(100)') as Param2Value, 

         -- Param3           
         TBL.SParam.value('local-name((*)[3])', 'varchar(50)') as Param3Name,
         TBL.SParam.value('(*)[3]', 'varchar(100)') as Param3Value,

         -- Param 4
         TBL.SParam.value('local-name((*)[4])', 'varchar(50)') as Param4Name,
         TBL.SParam.value('(*)[4]', 'varchar(100)') as Param4Value,

         -- Param 5
         TBL.SParam.value('local-name((*)[5])', 'varchar(50)') as Param5Name,
         TBL.SParam.value('(*)[5]', 'varchar(100)') as Param5Value

 FROM    @xmldoc.nodes('/NewDataSet/Table1') AS TBL(SParam)  

我需要一种方法来将它们来自 xml 文件的顺序添加到我的结果中。 (这是 Table1 的第一个实例,然后是第二个......)。

由于SQL table variable limitations 的原因,我不能使用标识列来保持这一点。 (由于其他原因,我不想使用临时表。)

我希望有一个很酷的 SQL XML 函数可以返回某种内部分配的节点 ID。 (或其他类似的排序方式。)

请注意,我不控制此 XML 结构(我只是一个读者),所以我无法更改以添加 ID 属性。

任何建议都会很棒!

编辑/更新:

我真的很想拥有这样的数据:

1 |共享参数 |共享 1 |另一个 |萨赫尔 1 |随机参数2 |好东西 1 |更多参数 |和更多 1 |结果参数 |和更多 2 |随机参数2 |你 2 |更多参数 |思考 2 |结果参数 | 2 3 |共享参数 |最后的 3 |另一个 |放 . . .

但我做得不够好。我可以将它放入列(或多或少),但我不知道如何进行编号。如果您有任何想法,我很想听听。

编辑:
我想出了执行此操作的查询(在互联网的帮助下)。它看起来像这样:

SELECT  TBL.SParam.value('local-name(.)[1]', 'varchar(50)') as ParamName,
        TBL.SParam.value('(.)[1]', 'varchar(50)') ParamValue, 
        TBL.SParam.value('for $s in . return count(../*[. << $s]) + 1', 'int') ParamPosition,
        TBL.SParam.value('for $s in . return count(../../*[. << $s]) - 1', 'int') ParamIteration 
FROM    @xmldoc.nodes('/NewDataSet/Table1/*') AS TBL(SParam)

【问题讨论】:

    标签: sql tsql sql-server-2008 xquery xquery-sql


    【解决方案1】:

    您可以使用数字表和position()

     SELECT  N.Number as ID,
             -- Param 1
             TBL.SParam.value('local-name((*)[1])', 'varchar(50)') as Param1Name,
             TBL.SParam.value('(*)[1]', 'varchar(100)') as Param1Value,             
             -- Param2
             TBL.SParam.value('local-name((*)[2])', 'varchar(50)') as Param2Name,
             TBL.SParam.value('(*)[2]', 'varchar(100)') as Param2Value, 
    
             -- Param3           
             TBL.SParam.value('local-name((*)[3])', 'varchar(50)') as Param3Name,
             TBL.SParam.value('(*)[3]', 'varchar(100)') as Param3Value,
    
             -- Param 4
             TBL.SParam.value('local-name((*)[4])', 'varchar(50)') as Param4Name,
             TBL.SParam.value('(*)[4]', 'varchar(100)') as Param4Value,
    
             -- Param 5
             TBL.SParam.value('local-name((*)[5])', 'varchar(50)') as Param5Name,
             TBL.SParam.value('(*)[5]', 'varchar(100)') as Param5Value
    
     FROM master..spt_values as N
        cross apply @xmldoc.nodes('/NewDataSet/Table1[position()=sql:column("N.Number")]') AS TBL(SParam)
     where N.type = 'P' and
           N.number between 1 and @xmlDoc.value('count(/NewDataSet/Table1)', 'int')
    

    【讨论】:

    • 为什么and N.number between 1 and @xmlDoc.value('count(/NewDataSet/Table1)', 'int')
    • @Conrad 数字表中的每一行都会发生交叉应用,因此当使用 master..spt_values 时,将对 XML 进行 2048 次查询。所以我认为最好先将数字表限制在实际需要的范围内。
    • @Conrad 一些快速测试表明(在我相当悲伤的笔记本电脑上)这个特定的查询需要 195 毫秒(没有between)和 4 毫秒。
    • 感谢您的回答。我意识到我需要我的结果有点不同(我更新了我的问题)。如果您愿意看一看,我将不胜感激。
    【解决方案2】:

    看看这个对Fully support position() in xquery的连接请求,请求者提供了一些可能对你有用的变通方法

    基于第二种解决方法,我编写了以下内容

    SELECT  
             p.number,
    
             TBL.SParam.value('local-name((*)[1])', 'varchar(50)') as Param1Name,
             TBL.SParam.value('(*)[1]', 'varchar(100)') as Param1Value,             
             -- Param2
             TBL.SParam.value('local-name((*)[2])', 'varchar(50)') as Param2Name,
             TBL.SParam.value('(*)[2]', 'varchar(100)') as Param2Value, 
    
             -- Param3           
             TBL.SParam.value('local-name((*)[3])', 'varchar(50)') as Param3Name,
             TBL.SParam.value('(*)[3]', 'varchar(100)') as Param3Value,
    
             -- Param 4
             TBL.SParam.value('local-name((*)[4])', 'varchar(50)') as Param4Name,
             TBL.SParam.value('(*)[4]', 'varchar(100)') as Param4Value,
    
             -- Param 5
             TBL.SParam.value('local-name((*)[5])', 'varchar(50)') as Param5Name,
             TBL.SParam.value('(*)[5]', 'varchar(100)') as Param5Value
     FROM    
        master..spt_values p CROSS APPLY 
    
    
         @xmldoc.nodes('NewDataSet/Table1[position()=sql:column("p.number")]') AS TBL(SParam)  
     WHERE P.type = 'P'
    

    返回以下内容

    number      Param1Name                                         Param1Value                                                                                          Param2Name                                         Param2Value                                                                                          Param3Name                                         Param3Value                                                                                          Param4Name                                         Param4Value                                                                                          Param5Name                                         Param5Value
    ----------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- -------------------------------------------------- ----------------------------------------------------------------------------------------------------
    1           Sharedparam                                        shared                                                                                               Antoher                                            sahre                                                                                                RandomParam2                                       Good stuff                                                                                           MoreParam                                          and more                                                                                             ResultsParam                                       2
    2           RandomParam2                                       do you                                                                                               MoreParam                                          think                                                                                                ResultsParam                                       2                                                                                                                                                       NULL                                                                                                                                                    NULL
    3           Sharedparam                                        Last                                                                                                 Antoher                                             Set                                                                                                 RandomParam2                                        of                                                                                                  MoreParam                                          values                                                                                               ResultsParam                                       are here
    4                                                              NULL                                                                                                                                                    NULL                                                                                                                                                    NULL                                                                                                                                                    NULL                                                                                                                                                    NULL
    
    (4 row(s) affected)
    

    【讨论】:

    • +1 :) 添加where type ='P' ,您可以删除不同的。
    • 感谢您的回答。我意识到我需要我的结果有点不同(我更新了我的问题)。如果您愿意看一看,我将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多