Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Distruzione di XML dai piani di esecuzione

Un modo molto diretto potrebbe essere questo (mentre @x è il tuo piano di esecuzione 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;  

Il risultato (non tutte le colonne)

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

L'id mostra chiaramente che l'algoritmo è prima l'ampiezza , non esiste id=1 (perché mai) e il nodetype permette di distinguere tra elementi, attributi e testo (fluttuante). Il prev la colonna punta a un fratello nella catena. Le colonne mancanti sono relative agli spazi dei nomi...

L'approccio con FROM OPENXML è obsoleto, ma questa è una delle rare situazioni in cui potrebbe essere ancora molto utile...

Ottieni un elenco con ID e ParentID che potresti interrogare con un CTE ricorsivo... Dipende da cosa vuoi fare con questo in seguito...