【问题标题】:Reading XML attribute values using OPENXML使用 OPENXML 读取 XML 属性值
【发布时间】:2020-07-29 08:11:38
【问题描述】:

对于以下 .nodes() 方法,我需要一个等效的 OPENXML 方法。属性会有所不同,不能硬编码。

DECLARE @Xml XML='<row>
                     <DeletedVal>
                        <row attribute1="value1" attribute2="value2"/>
                     </DeletedVal>
                   </row>';

SELECT x1.y.value('local-name(.)', 'VARCHAR(30)') AS [Key]
       , x1.y.value('.', 'VARCHAR(MAX)')          AS [Value]
FROM   @Xml.nodes('/row/DeletedVal//@*') x1(y)

输出:

Key                            Value
------------------------------ ------
attribute1                     value1
attribute2                     value2

以下 OPENXML 方法需要修复,我不确定如何获取属性。

DECLARE @DocHandle INT
EXEC sp_xml_preparedocument
  @DocHandle OUTPUT
  , @Xml;

SELECT *
FROM   OPENXML (@docHandle, N'/row/DeletedVal//@*')
          WITH ([Key]     VARCHAR(10) 'key' --- This line needs editing
                , [Value] VARCHAR(10) '.')

EXEC Sp_xml_removedocument
  @DocHandle; 

输出:

Key        Value
---------- ----------
NULL       value1
NULL       value2

【问题讨论】:

  • 为什么要使用更旧的功能而 XQUERY?
  • 我不知道 XQUERY 我的服务器也运行 SQL Server 2012。我的 SQL Server 版本是否支持 XQUERY?
  • XQUERY 自 SQL Server 2005 起就受支持(如果我没记错的话),并且是您在第一条语句中使用的。
  • 在获取执行计划时,OPENXML 仅占 5%,而 XQUERY(.nodes()) 占 95%。所以 OPENXML 更好吧?
  • 较低的数字并不意味着“更好”,不。 XQUERY 是要走的路。旧的sp_xml_preparedocument 更多地保留在 SQL Server 中以实现向后兼容性。

标签: sql-server xml tsql openxml sql-server-openxml


【解决方案1】:

正如@Larnu 正确指出的那样,保留Microsoft 专有的OPENXML 及其伙伴sp_xml_preparedocumentsp_xml_removedocument 只是为了与过时的SQL Server 2000 向后兼容。

强烈建议重新编写 SQL 并将其切换到 XQuery。从 2005 年开始,它在 MS SQL Server 中可用。

我通过从 .nodes() XQuery 方法中删除 //@*(向下搜索后代)对您的 T-SQL 进行了一些性能改进。

DECLARE @Xml XML = 
N'<row>
    <DeletedVal>
        <row attribute1="value1" attribute2="value2"/>
    </DeletedVal>
</row>';

SELECT c.value('local-name(.)', 'VARCHAR(30)') AS [Key]
    , c.value('.', 'VARCHAR(MAX)') AS [Value]
FROM   @Xml.nodes('/row/DeletedVal/row/@*') AS t(c);

输出

+------------+--------+
|    Key     | Value  |
+------------+--------+
| attribute1 | value1 |
| attribute2 | value2 |
+------------+--------+

【讨论】:

    【解决方案2】:

    参考这个link,我找到了如下解决方案:

    DECLARE @Xml XML='<row><DeletedVal><row attribute1="value1" attribute2="value2"/></DeletedVal></row>';
    DECLARE @DocHandle INT
    
    EXEC sp_xml_preparedocument
      @DocHandle OUTPUT
      , @Xml;
    
    SELECT *
    FROM   OPENXML (@docHandle, N'/row/DeletedVal//@*')
              WITH ([Key]     VARCHAR(10) '@mp:localname'
                    , [Value] VARCHAR(10) '.')
    
    EXEC Sp_xml_removedocument
      @DocHandle; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-19
      • 1970-01-01
      • 2010-10-30
      • 2022-01-13
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多