【问题标题】:SQL Using OpenXML to retrieve multiple ElementsSQL 使用 OpenXML 检索多个元素
【发布时间】:2017-12-03 04:23:44
【问题描述】:

我正在使用 OpenXML 查询以检索 XML 中主题元素之间的上限元素我不希望支持元素之间的上限。该查询可以很好地检索一个值,但在有多个元素节点时会失败。

      <First>
         <Test id="83847">
            <subject>
               <cap>15</cap>
               <cap>25</cap>
               <cap>100</cap>
            </subject>
            <support>
               <cap>9</cap>
            </support>
          </Test>
        <Test id="83848">
            <subject>
               <cap>150</cap>
               <cap>2</cap>
               <cap>10</cap>
            </subject>
             <support>
               <cap>9</cap>
            </support>
          </Test>
      </First>

CREATE Table #XmlTemp(XmlField Xml);
Set Nocount On;
Insert Into #XmlTemp(XmlField)
Select '<First>
         <Test id="83847">
             <subject>
                <cap>15</cap>
                <cap>25</cap>
                <cap>100</cap>
             </subject>
             <support>
                <cap>9</cap>
             </support>
          </Test>
        <Test id="83848">
            <subject>
               <cap>150</cap>
               <cap>2</cap>
               <cap>10</cap>
            </subject>
             <support>
               <cap>9</cap>
            </support>
          </Test>
      </First>'As XmlField;

Declare @xmlData Xml;
Select @xmlData = XmlField From #XmlTemp;

Declare @document int;
Exec sp_xml_preparedocument @document Output, @xmlData, NULL;


SELECT ID,Cap FROM(
SELECT ID,Cap FROM OpenXml(@document,'./First/Test', 0) With (ID varchar(max)'./@id', Cap Varchar(max) './subject/cap')) alias

drop table #xmltemp

将查询更改为使用 .nodes 方法会相当耗时,因为涉及到测试,所以如果可能的话,我希望它保持为 OpenXML。 我只想检索 ID,然后检索多个 cap 元素值。

感谢您的宝贵时间。

【问题讨论】:

  • FROM OPENXML 与相应的 SP 准备和删除文档已过时,不应再使用(存在罕见的例外情况)。而是使用适当的methods the XML data type provides

标签: sql-server xml xpath xquery openxml


【解决方案1】:

我不明白为什么使用 .nodes 的查询很复杂。只是

SELECT t.n.value('(/First/Test/@id)[1]', 'int') id
   , t.n.value('(.)[1]', 'int') cap
from @xmlData.nodes('./First/Test/subject/cap') t(n);

还有 OpenXML 版本

SELECT ID,Cap FROM(
    SELECT ID,Cap 
    FROM OpenXml(@document,'./First/Test/subject/cap', 0) 
       With (ID varchar(max) '/First/Test/@id'
          , Cap Varchar(max) '.')) alias

已编辑问题的版本

SELECT ID,Cap FROM(
    SELECT ID,Cap 
    FROM OpenXml(@document,'/First/Test/subject/cap', 0) 
       With (ID varchar(max) '../../@id'
          , Cap Varchar(max) '.')) alias

它只返回正确父级的subject/cap@id

    ID  Cap
1   83847   15
2   83847   25
3   83847   100
4   83848   150
5   83848   2
6   83848   10

【讨论】:

  • 并不复杂。只是在测试希望避免的更改时产生大量额外开销。
  • 我想这让它更具挑战性,但 XML 更长,还有其他 cap 元素,但我只希望主题元素之间的那些不支持你的代码只获取第一个 id 属性而可能有多个。请参阅已编辑的问题。谢谢!
  • 好的,需要从上限的路径指定父级。见编辑。
  • 完美。谢谢!!
  • @Shnugo,xml.nodes 版本是在 OP 编辑​​他的问题之前创建的,并且由于与 OpenXML 版本无关而被放弃。
【解决方案2】:

您的 XML 是双重嵌套的。在&lt;First&gt; 中有1:n&lt;Test&gt; 元素,在&lt;subject&gt; 中有1:n&lt;cap&gt; 元素。

查询此问题的正确方法是严格向前深入研究 XML

CREATE Table #XmlTemp(XmlField Xml);
Set Nocount On;
Insert Into #XmlTemp(XmlField)
Select '<First>
         <Test id="83847">
             <subject>
                <cap>15</cap>
                <cap>25</cap>
                <cap>100</cap>
             </subject>
             <support>
                <cap>9</cap>
             </support>
          </Test>
        <Test id="83848">
            <subject>
               <cap>150</cap>
               <cap>2</cap>
               <cap>10</cap>
            </subject>
             <support>
               <cap>9</cap>
            </support>
          </Test>
      </First>'As XmlField;

--查询将使用.nodes() 获取所有&lt;Test&gt; 元素并再次使用.nodes() 获取相关&lt;cap&gt; 元素:

      SELECT t.value('@id', 'int') id
            ,c.value('text()[1]', 'int') cap
    from #XmlTemp AS tbl
    CROSS APPLY tbl.XmlField.nodes('/First/Test') AS A(t)
    CROSS APPLY A.t.nodes('subject/cap') AS B(c);
GO
DROP TABLE #XmlTemp;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 2020-04-26
    • 1970-01-01
    相关资源
    最近更新 更多