SQL: использование XML в качестве входных данных для внутреннего объединения - PullRequest
1 голос
/ 24 октября 2019

У меня есть входящий XML, но мне неясно, как мне нужно настроить данные и оператор для получения значений из него. Мой XML выглядит следующим образом:

<Keys>
    <key>246</key>
    <key>247</key>
    <key>248</key>
</Keys>

И я хочу сделать следующее (упрощено, чтобы донести свою точку зрения)

Select *
From Transaction as t
Inner Join @InputXml.nodes('Keys') as K(X)
    on K.X.value('@Key', 'INT') = t.financial_transaction_grp_key

Может кто-нибудь представить, как я это сделаю? Как будет выглядеть моя третья / четвертая строка в SQL? Спасибо!

Ответы [ 2 ]

0 голосов
/ 25 октября 2019

Из вашего кода я предполагаю, что это SQL-сервер, но вы добавили тег [mysql] ...
. Для вашего следующего вопроса, пожалуйста, имейте в виду, что очень важно знать ваши инструменты (поставщик и версия).

Предполагая, что T-SQL и [sql-server] (согласно предоставленному образцу кода) вы были близки:

DECLARE @InputXml XML=
N'<Keys>
    <key>246</key>
    <key>247</key>
    <key>248</key>
</Keys>';

DECLARE @YourTransactionTable TABLE(ID INT IDENTITY,financial_transaction_grp_key INT);
INSERT INTO @YourTransactionTable VALUES (200),(246),(247),(300);

Select t.*
From @YourTransactionTable as t
Inner Join @InputXml.nodes('/Keys/key') as K(X)
    on K.X.value('text()[1]', 'INT') = t.financial_transaction_grp_key;

Что было не так:

  • .nodes() должен перейти к повторяющемуся элементу, который <key>
  • В .value() вы используете путь @Key, который неверен с двух сторон: 1) <key> является элементом ине является атрибутом и 2) XML строго учитывает регистр, поэтому Key!=key.

Альтернативой может быть следующее:

WHERE @InputXml.exist('/Keys/key[. cast as xs:int? = sql:column("financial_transaction_grp_key")]')=1;

Какой из них быстрее, зависит от количествастрок в исходной таблице, а также количество ключей в вашем XML. Просто попробуйте.

0 голосов
/ 24 октября 2019

Возможно, вам нужно проанализировать XML в читаемый формат с помощью регулярного выражения.

Я написал подобное событие для анализа активной БД из xmlpayload, который был сохранен в таблице. Это может или не может работать для вас, но вы должны быть в состоянии, по крайней мере, начать.

SELECT SUBSTRING(column FROM IF(locate('<key>',column)=0,0,0+LOCATE('<key>',column))) as KEY FROM table LIMIT 1\G

...