Запрос из столбца XML - PullRequest
0 голосов
/ 15 июня 2019

Эти результаты находятся в столбце xml таблицы.

<?xml version="1.0" encoding="UTF-8"?>
<client id_issue="5488">
<surname value="Hasanov"/>
<name value="Mehman"/>
<middle_name value="Adil"/>
<date_birth value="1986-05-19"/>
</client>

Я хочу запросить значения фамилии, имени, отчества и даты_бирта из столбца xml.

Как показано ниже:

surname    name    middle_name    date_birth` 
----------------------------------------------   
Hasanov    Mehman   Adil         1986-05-19

Ответы [ 3 ]

3 голосов
/ 15 июня 2019

Вы можете использовать:

SELECT s.c.value('@id_issue', 'INT') AS id_issue
     ,s.c.value('surname[1]/@value', 'NVARCHAR(100)') AS surname
     ,s.c.value('name[1]/@value', 'NVARCHAR(100)') AS name
     ,s.c.value('middle_name[1]/@value', 'NVARCHAR(100)') AS middle_name
     ,s.c.value('date_birth[1]/@value', 'DATE') AS dob
FROM tab
CROSS APPLY tab.col.nodes('/client') s(c);

дБ <> демонстрация скрипки


EDIT:

У меня ошибка ... Сообщение 9506, уровень 16, состояние 1, строка 1 «Узлы» метода XMLDT можно вызывать только для столбцов типа xml. мой тип столбца xml - ntext

NTEXT устарело . Вы можете привести NTEXT к XML, а затем проанализировать его.

SELECT s.c.value('@id_issue', 'INT') AS id_issue
     ,s.c.value('surname[1]/@value', 'NVARCHAR(100)') AS surname
     ,s.c.value('name[1]/@value', 'NVARCHAR(100)') AS name
     ,s.c.value('middle_name[1]/@value', 'NVARCHAR(100)') AS middle_name
     ,s.c.value('date_birth[1]/@value', 'DATE') AS dob
FROM tab
CROSS APPLY (SELECT TRY_CAST(REPLACE(CAST(tab.col AS NVARCHAR(MAX)),'<?xml version="1.0" encoding="UTF-8"?>','') AS XML)) sub(col)
CROSS APPLY sub.col.nodes('/client') s(c)

db <> демонстрация скрипки

0 голосов
/ 18 июня 2019

Worked with this query

SELECT

CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/ surname/@value)[1]', 'nvarchar(max)') AS surname,

CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/ name/@value)[1]', 'nvarchar(max)') AS [name],

CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/ middle_name/@value)[1]', 'nvarchar(max)') AS middle_name,

CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/ date_birth/@value)[1]', 'nvarchar(max)') AS date_birth

0 голосов
/ 16 июня 2019

Вы можете использовать XQuery следующим образом:

DECLARE @q XML= '<?xml version="1.0" encoding="UTF-8"?>
    <client id_issue="5488">
        <surname value="Hasanov"/>
        <name value="Mehman"/>
        <middle_name value="Adil"/>
        <date_birth value="1986-05-19"/>
    </client>';

SELECT @q.value('(client/surname/@value)[1]', 'varchar(max)') AS surname,
       @q.value('(client/name/@value)[1]', 'varchar(max)') AS name,
       @q.value('(client/middle_name/@value)[1]', 'varchar(max)') AS middle_name,
       @q.value('(client/date_birth/@value)[1]', 'date') AS date_birth;

Подробнее о XQuery: https://docs.microsoft.com/en-us/sql/xquery/xquery-language-reference-sql-server?view=sql-server-2017

Если у вас есть таблица, и вы собираетесь анализировать xml внутри таблицы, которую выможно попробовать это, что похоже на вышеупомянутое решение:

Предположим, у вас есть такая таблица:

CREATE TABLE tblTest
(
    id INT PRIMARY KEY,
    msg XML
);

, и вы вставили в эту таблицу некоторые данные, подобные этой:

INSERT INTO tblTest
VALUES
(1,
 '<?xml version="1.0" encoding="UTF-8"?>
    <client id_issue="5488">
        <surname value="Hasanov"/>
        <name value="Mehman"/>
        <middle_name value="Adil"/>
        <date_birth value="1986-05-19"/>
    </client>'),
(2,
 '<?xml version="1.0" encoding="UTF-8"?>
    <client id_issue="5488">
        <surname value="Alimov"/>
        <name value="Ghader"/>
        <middle_name value="Ragman"/>
        <date_birth value="1950-04-20"/>
    </client>');

Таким образом, вы можете просто проанализировать его с помощью XQuery следующим образом:

SELECT msg.value('(client/surname/@value)[1]', 'varchar(max)') AS surname,
       msg.value('(client/name/@value)[1]', 'varchar(max)') AS name,
       msg.value('(client/middle_name/@value)[1]', 'varchar(max)') AS middle_name,
       msg.value('(client/date_birth/@value)[1]', 'date') AS date_birth
FROM tblTest;

Даже если ваш msg не имеет типа данных XML (например, это будет varchar(max)), тогда вам нужнопреобразовать его в xml до запроса с использованием XQuery следующим образом:

SELECT CAST(msg AS XML).value('(client/surname/@value)[1]', 'varchar(max)') AS surname,
       CAST(msg AS XML).value('(client/name/@value)[1]', 'varchar(max)') AS name,
       CAST(msg AS XML).value('(client/middle_name/@value)[1]', 'varchar(max)') AS middle_name,
       CAST(msg AS XML).value('(client/date_birth/@value)[1]', 'date') AS date_birth
FROM tblTest;

Если при выполнении вышеуказанного запроса вы сталкиваетесь со следующей ошибкой:

невозможно переключить кодировку

Вы можете переписать его следующим образом:

SELECT CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/surname/@value)[1]', 'nvarchar(max)') AS surname,
       CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/name/@value)[1]', 'nvarchar(max)') AS [name],
       CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/middle_name/@value)[1]', 'nvarchar(max)') AS middle_name,
       CAST(REPLACE(CAST([msg] AS NVARCHAR(MAX)), 'encoding="utf-8"', '') AS XML).value('(client/date_birth/@value)[1]', 'nvarchar(max)')AS date_birth
FROM tblTest;

И, наконец, если вам нужно использовать результат вышеупомянутого запроса в другом запросе (например, JOIN to to other отношение), вы можете поместить егов качестве подзапроса и использовать его.

SELECT K.surname,
       K.name,
       K.middle_name,
       K.date_birth
FROM
(
    SELECT msg.value('(client/surname/@value)[1]', 'varchar(max)') AS surname,
           msg.value('(client/name/@value)[1]', 'varchar(max)') AS name,
           msg.value('(client/middle_name/@value)[1]', 'varchar(max)') AS middle_name,
           msg.value('(client/date_birth/@value)[1]', 'date') AS date_birth
    FROM tblTest
) AS K INNER JOIN ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...