Извлечение нескольких значений из столбца таблицы, ранее приведенного к XML - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть столбец таблицы как nvarchar (max), содержащий следующие данные XML:

<?xml version="1.0" encoding="utf-8"?>
<SerializableAlertDetail xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="SerializableContextAlertDetail">
  <ContextName>Evénements PTI mobile</ContextName>
  <EnumValueName>Pré Alerte immobilisme</EnumValueName>
</SerializableAlertDetail>

Я хотел бы ВЫБЕРИТЬ конкатенацию XML-элементов 'ContextName' и 'EnumValueName'.

Сначала я просто попытался вернуть один элемент, который отлично работает:

SELECT CAST(REPLACE(dbo.AlertDetail.Context, 'encoding="utf-8"', '') AS XML).value('(/SerializableAlertDetail/*[local-name() = "ContextName"])[1]', 'nvarchar(max)') As DisplayName FROM Table

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

SELECT T0.XML.value('ContextName', 'nvarchar(max)')
FROM Table c
    CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X)
    CROSS APPLY T.X.nodes('SerializableAlertDetail') AS T0(XML)

Но он завершается ошибкой со следующим сообщением об ошибке:

XQuery [TXvalue ()]: 'value ()'требуется одиночный (или пустая последовательность) найденный операнд типа' xdt: untypedAtomic * '

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ 1


Я пришел к следующему запросу, который работает, но, возможно, не оптимален:

SELECT T0.XML.query('./ContextName').value('.', 'nvarchar(max)') + T0.XML.query('./EnumValueName').value('.', 'nvarchar(max)')
FROM Table c
        CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X)
        CROSS APPLY T.X.nodes('SerializableAlertDetail') AS T0(XML)

РЕДАКТИРОВАТЬ 2


Заменентекст от nvarchar (max);)

1 Ответ

0 голосов
/ 08 февраля 2019

Вам уже говорили, что NTEXT устарел на протяжении веков; -)

Просто некоторый фон:

NTEXT - это 2-байтовый кодированный тексти переведем на NVARCHAR.Но ваш XML кричит Я UTF-8 !!!! , что является простой ложью.В пределах NTEXT это точно!- не UTF-8.Существует два подхода:

  • Приведите ваш NTEXT к NVARCHAR, затем к VARCHAR и, наконец, к XML.Это будет работать, так как UTF-8 1-байтовый кодированный в простом латинском.
  • Уберите ложь, заменив utf-8 на 1) ничто (как вы делаете), с 2) utf-16 или с 3) ucs-2 (правильная вещь).

О вашем запросе: это можно сделать немного проще, так как нет повторяющегося содержимого, поэтому нет необходимостидля производной таблицы.Попробуйте это:

SELECT X.value('(/SerializableAlertDetail/ContextName/text())[1]','nvarchar(max)') 
     + X.value('(/SerializableAlertDetail/EnumValueName/text())[1]','nvarchar(max)')
FROM Table c
        CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X);

Это должно быть быстрее ...

С точки зрения читабельности вы можете даже попробовать

SELECT X.value('(//ContextName)[1]','nvarchar(max)') 
     + X.value('(//EnumValueName)[1]','nvarchar(max)')
FROM Table c
        CROSS APPLY (SELECT CAST(REPLACE(c.Context, 'encoding="utf-8"', '') AS XML)) as T(X);
...