T- SQL синтаксический анализ XML данных в одну строку - PullRequest
0 голосов
/ 03 августа 2020

У меня XML сохранено в столбце таблицы как тип nvarchar. Теперь мне нужно проанализировать данные из этого xml. Я использую

SELECT
    CONVERT(XML, columnX).value('(chatTranscript/message/msgText/text())[1]', 'nvarchar(max)') 

как чат, но получаю только первое значение. Как мне собрать все в одну строку? XML может быть длинным, зависит от продолжительности чата.

Мне нужно набрать userNick, а затем msgText и l oop до конца. Примерно так:

userX:Hello<>userY:How are you; 

XML:

<?xml version="1.0"?>
<chatTranscript startAt="2020-07-30T11:00:12Z" sessionId="......">
    <newParty userId="......" timeShift="0" visibility="ALL" eventId="1">
        <userInfo personId="" userNick="userX"/>
    </newParty>
    <message userId="..." timeShift="12" visibility="ALL" eventId="9">
        <msgText msgType="text">Hello</msgText>
    </message>
    <newParty userId="..." timeShift="15" visibility="ALL" eventId="10">
        <userInfo userNick="userY"/>
    </newParty>
    <message userId="..." timeShift="29" visibility="ALL" eventId="12">
        <msgText treatAs="NORMAL">how are you?</msgText>
    </message>
    <partyLeft userId="..." timeShift="36" visibility="ALL" eventId="13" askerId="...">
        <reason code="1">left with request to close if no agents</reason>
    </partyLeft>
    <partyLeft userId="..." timeShift="36" visibility="ALL" eventId="14" askerId="...">
        <reason code="4">removed by other party</reason>
    </partyLeft>
</chatTranscript>

Ответы [ 2 ]

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

Для этого вам нужен код. Попытка сделать то, о чем вы просите, будет очень грязной T- SQL. Я бы рекомендовал разобрать xml в коде, чтобы сгенерировать то, что вы хотите, на основе этого xml. Вы также можете создать функцию CLR, используя код, чтобы вы могли создать для этого функцию SQL. Вы можете делать удивительные вещи с XQuery и T- SQL, но иногда это просто беспорядок. Для xml манипуляций внутри базы данных идеально подходят функции CLR.

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

Вот мое решение:

ALTER FUNCTION [dbo].[fn_parse_chat_xml] (@xml XML) 
RETURNS NVARCHAR(MAX) 
BEGIN 
    DECLARE @n INT, @content NVARCHAR(MAX), @userId NVARCHAR(200), @userNick1 NVARCHAR(200), @userNick2 NVARCHAR(200), @userNickX NVARCHAR(200)
    SET @n = 1 
    SET @userId = @xml.value('(chatTranscript/newParty/@userId)[1]', 'nvarchar(max)')
    SET @userNick1 = @xml.value('(chatTranscript/newParty/userInfo/@userNick)[1]', 'nvarchar(max)')
    SET @userNick2 = @xml.value('(chatTranscript/newParty/userInfo/@userNick)[2]', 'nvarchar(max)')
    WHILE DATALENGTH(@xml.value('(chatTranscript/message/msgText/text())[sql:variable("@n")][1]', 'nvarchar(max)'))>0 
        BEGIN        
            IF @userId = @xml.value('(chatTranscript/message/@userId)[sql:variable("@n")][1]', 'nvarchar(max)') 
                SET @userNickX = @userNick1
            else 
                SET @userNickX = @userNick2 
            SET @content = concat(@content, ' <> ', @userNickX, ': ', @xml.value('(chatTranscript/message/msgText/text())[sql:variable("@n")][1]', 'nvarchar(max)'))
            SET @n = @n + 1
        END
    RETURN @content
END
...