sql - 从执行计划中分解 XML

标签 sql sql-server xml tsql sql-execution-plan

首先,我会说我讨厌 XML,这是一种可怕的东西,但有时是必要的。

我当前的问题是,我正在尝试从执行计划(由用户提供,因此可以是任何大小)中获取 XML,并将其分解到一个表中以供进一步操作。我现在只有两个选择;

  1. 我可以计算出可用于执行计划的最大节点数(我怀疑这会很多)并创建可用于任何 XML 输入的整个脚本。这是一次性的事情,所以不是问题。
  2. 另一种方法是动态计算节点数并根据要求创建输出。

过去有没有人做过类似的练习?我发现的所有示例查询都已经知道输出字段。

最佳答案

一个非常直接的方法可能是这样(而 @x 是您的 XML 执行计划):

DECLARE @x XML=
N'<root>
    <ElementE1 AttributA1="A1-text belongs to E1[1]" OneMore="xyz">E1-Text 2</ElementE1>
    <ElementE1 AttributA1="A1-text belongs to E1[2]">E1-Text 2</ElementE1>
    <ElementParent>
      <subElement test="sub"/>
      Free text
    </ElementParent>
  </root>';

DECLARE @idoc INT;
EXEC sp_xml_preparedocument @idoc OUTPUT, @x;   
SELECT * FROM OPENXML (@idoc, '*');   
EXEC sp_xml_removedocument @idoc;  

结果(不是所有列)

+----+----------+----------+--------------+------+--------------------------+
| id | parentid | nodetype | localname    | prev | text                     |
+----+----------+----------+--------------+------+--------------------------+
| 0  | NULL     | 1        | root         | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 2  | 0        | 1        | ElementE1    | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 3  | 2        | 2        | AttributA1   | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 13 | 3        | 3        | #text        | NULL | A1-text belongs to E1[1] |
+----+----------+----------+--------------+------+--------------------------+
| 4  | 2        | 2        | OneMore      | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 14 | 4        | 3        | #text        | NULL | xyz                      |
+----+----------+----------+--------------+------+--------------------------+
| 5  | 2        | 3        | #text        | NULL | E1-Text 2                |
+----+----------+----------+--------------+------+--------------------------+
| 6  | 0        | 1        | ElementE1    | 2    | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 7  | 6        | 2        | AttributA1   | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 15 | 7        | 3        | #text        | NULL | A1-text belongs to E1[2] |
+----+----------+----------+--------------+------+--------------------------+
| 8  | 6        | 3        | #text        | NULL | E1-Text 2                |
+----+----------+----------+--------------+------+--------------------------+
| 9  | 0        | 1        | ElementParent| 6    | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 10 | 9        | 1        | subElement   | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 11 | 10       | 2        | test         | NULL | NULL                     |
+----+----------+----------+--------------+------+--------------------------+
| 16 | 11       | 3        | #text        | NULL | sub                      |
+----+----------+----------+--------------+------+--------------------------+
| 12 | 9        | 3        | #text        | 10   | Free text                |
+----+----------+----------+--------------+------+--------------------------+

id 清楚地表明该算法是广度优先,没有id=1(为什么永远如此)和nodetype 允许区分元素、属性和( float )文本。 prev 列指向链中的一个兄弟。缺少的列与命名空间有关...

FROM OPENXML 的方法已经过时,但这是它可能仍然非常有用的罕见情况之一...

您会得到一个包含 ID 和 ParentID 的列表,您可能会使用递归 CTE 查询...这取决于您之后想用它做什么...

关于sql - 从执行计划中分解 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39347880/

相关文章:

sql-server - Count() 的问题

SQL 获取销售额超过一定数量的商品数量

xml - 从不同的文档 xslt 2.0 复制时命名空间问题

c# - 我应该使用哪个框架和数据库?

mysql - sql 4年活跃成员(member)表结构

php - 该行在 MySQL 中没有被删除并且 PHP 没有返回错误

sql - 使用 SQL 查询包含重复数据的 XML

sql - 如果可用,请在该月加入,否则请在最近一个月加入

sql - Polybase EXTERNAL TABLE 访问失败 - 权限被拒绝

android - 对 Android Studio 中的 Scrollview 滚动问题进行故障排除