SQL - Как вставить уникальный идентификатор в тег XML - PullRequest
1 голос
/ 02 июня 2019

Я получаю фиксированный XML из внешней системы, и мне нужно в T-SQL добавить некоторый уникальный идентификатор в тег <document> и вставить все данные в 2 таблицы.

Это XML, который я получаю:

<root>
    <document number="1234">
        <data1>
            <item1 d="100"/> 
            <item1 d="200"/> 
        </data1>
        <data2>
            <item2 d="111"/> 
            <item2 d="222"/> 
        </data2>
    </document> 
    <document number="1234">
        <data1>
            <item1 d="300"/> 
            <item1 d="400"/> 
        </data1>
    </document> 
    <document number="1234">
        <data1>
            <item1 d="500"/> 
        </data1>
        <data2>
            <item2 d="555"/> 
        </data2>
    </document> 
</root>

Мне нужно вставить вышеуказанный XML в 2 таблицы tData1 и tData2 с уникальным docid на уровне <document>.

Таблица tData1 должна выглядеть следующим образом:

docid    number     d
---------------------
    1      1234   100
    1      1234   200
    2      1234   300
    2      1234   400
    3      1234   500

Таблица tData2 должна выглядеть следующим образом:

docid    number    d
---------------------
    1      1234   111
    1      1234   222
    3      1234   555

Как вставить поле docid при преобразовании вышеуказанного XML в эти таблицы?

1 Ответ

2 голосов
/ 02 июня 2019

Вы можете использовать nodes в CROSS APPLY, например:

DECLARE @x XML='<root>
    <document number="1234">
        <data1>
            <item1 d="100"/> 
            <item1 d="200"/> 
        </data1>
        <data2>
            <item2 d="111"/> 
            <item2 d="222"/> 
        </data2>
    </document> 
    <document number="1234">
        <data1>
            <item1 d="300"/> 
            <item1 d="400"/> 
        </data1>
    </document> 
    <document number="1234">
        <data1>
            <item1 d="500"/> 
        </data1>
        <data2>
            <item2 d="555"/> 
        </data2>
    </document> 
</root>'


SELECT Q1.docid, Q1.number, Q2.d
FROM (
    SELECT  ROW_NUMBER() OVER (ORDER BY T1.N1) AS docid,
            N1.value('@number','varchar(10)') AS number,
            N1.query('.') AS X
    FROM @x.nodes('root/document') T1(N1)
) Q1
CROSS APPLY (
    SELECT N2.value('@d','varchar(10)') AS d
    FROM Q1.x.nodes('document/data1/item1') T2(N2)
) Q2

SELECT Q1.docid, Q1.number, Q2.d
FROM (
    SELECT  ROW_NUMBER() OVER (ORDER BY T1.N1) AS docid,
            N1.value('@number','varchar(10)') AS number,
            N1.query('.') AS X
    FROM @x.nodes('root/document') T1(N1)
) Q1
CROSS APPLY (
    SELECT N2.value('@d','varchar(10)') AS d
    FROM Q1.x.nodes('document/data2/item2') T2(N2)
) Q2

Для генерации docid Я использовал ROW_NUMBER над столбцом узла, как объяснено в http://dataeducation.com/uniquely-identifying-xml-nodes-with-dense_rank/.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...