Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

XML aus Ausführungsplänen schreddern

Ein sehr direkter Weg könnte dieser sein (während @x ist Ihr XML-Ausführungsplan):

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;  

Das Ergebnis (nicht alle Spalten)

+----+----------+----------+--------------+------+--------------------------+
| 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                |
+----+----------+----------+--------------+------+--------------------------+

Die id zeigt deutlich, dass der Algorithmus Breite zuerst ist , gibt es kein id=1 (warum auch immer) und der nodetype ermöglicht die Unterscheidung zwischen Elementen, Attributen und (floating) Text. Die prev Spalte zeigt auf ein Geschwister oben in der Kette. Die fehlenden Spalten beziehen sich auf Namespaces...

Der Ansatz mit FROM OPENXML ist veraltet, aber dies ist eine der seltenen Situationen, in denen es immer noch sehr nützlich sein könnte ...

Sie erhalten eine Liste mit IDs und ParentIDs, die Sie mit einem rekursiven CTE abfragen könnten... Das hängt davon ab, was Sie danach damit machen wollen...