Выбор данных из XML - PullRequest
       59

Выбор данных из XML

0 голосов
/ 06 августа 2020

Я пытаюсь вставить строку на основе данных, извлеченных из фрагмента XML. Некоторые столбцы должны быть инициализированы значениями узлов, пара узлов «глубоко» в структуре XML.

Я не могу правильно ответить на запрос. Вот что я получил:

declare @xmlRaw xml = '
    <LogEntry>
        <SummaryMessage>Something bad happened</SummaryMessage>
        <Exception>
            <Type>System.ApplicationException</Type>
            <Message>A test of the error handling</Message>
        </Exception>
    </LogEntry>'

select
    LogEntryColumn.value('SummaryMessage[1]', 'varchar(10)') as SummaryMessage, -- works fine
    LogEntryColumn.query('Exception[1]').value('Message[1]', 'varchar(10)') as ExMessage -- not working
from 
    @xmlRaw.nodes('LogEntry[1]') as LogEntryTable(LogEntryColumn)

Это выводит:

SummaryMessage ExMessage
-------------- ----------
Something      NULL

Я пробовал множество вариантов для запроса столбца «ExMessage», но без радости.

Обратите внимание, что я использую «LogEntryColumn.query (...). Value (...)», потому что я хочу проверить, как эта форма работает по сравнению с чем-то вроде:

select
    LogEntryColumn.value('SummaryMessage[1]', 'varchar(10)') as SummaryMessage, -- works fine
    ExceptionEntryColumn.value('Message[1]', 'varchar(10)') as ExMessage -- not working
from 
    @xmlRaw.nodes('LogEntry[1]') as LogEntryTable(LogEntryColumn)
    outer apply @xmlData.nodes('LogEntry[1]/Exception') as ExceptionTable(ExceptionEntryColumn)

В основном я интересно, лучше или хуже несколько предложений "external apply" from, чем несколько вызовов .query (...).

1 Ответ

1 голос
/ 06 августа 2020

Вот что вам нужно.

SQL

DECLARE @xmlRaw XML = 
N'<LogEntry>
    <SummaryMessage>Something bad happened</SummaryMessage>
    <Exception>
        <Type>System.ApplicationException</Type>
        <Message>A test of the error handling</Message>
    </Exception>
</LogEntry>';

SELECT c.value('(SummaryMessage/text())[1]', 'varchar(100)') AS SummaryMessage
    , c.value('(Exception/Message/text())[1]', 'varchar(100)') AS ExMessage 
FROM @xmlRaw.nodes('/LogEntry') AS t(c);

Выход

+------------------------+------------------------------+
|     SummaryMessage     |          ExMessage           |
+------------------------+------------------------------+
| Something bad happened | A test of the error handling |
+------------------------+------------------------------+
...