简体   繁体   English

使用MS SQL修改XML列

[英]Modify XML column using MS SQL

I've these 2 XML which is stored in 2 tables. 我有这两个XML存储在2个表中。

Question XML 问题XML

<Question>
    <Choice ID="1">
        <Value>Choice A</Value>
    </Choice>
    <Choice ID="2">
        <Value>Choice B</Value>
    </Choice>
    <Choice ID="3">
        <Value>Choice C</Value>
    </Choice>
    <Choice ID="4">
        <Value>Choice D</Value>
    </Choice>
    <Choice ID="5">
        <Value>Choice E</Value>
    </Choice>
</Question>

Response XML 响应XML

<Response>
    <Question>
        <Value>Choice B</Value>
        <Value>Choice C</Value>
    </Question>
</Response>

I need to add a new attribute called ID , to all the Value elements present in the Response XML . 我需要向Response XML中的所有Value元素添加一个名为ID新属性 The value of the new ID attribute can be found in the Question XML . 可以在问题XML中找到新ID属性的

For Instance, If you see the Question XML , the correct ID of the value Choice B is 2 and Choice C is 3 对于Instance,如果您看到Question XML ,则值Choice B is 2的正确ID Choice B is 2Choice C is 3

So the final Response XML which i need, should be like this 所以我需要的最终Response XML应该是这样的

<Response>
    <Question>
        <Value ID="2">Choice B</Value>
        <Value ID="3">Choice C</Value>
    </Question>
</Response>

Can someone please tell me how to do this ? 有人可以告诉我该怎么做?

If you want to modify more than one place in an XML in most cases the best is to shredd the information and re-build the XML from scratch: 如果要在大多数情况下修改XML中的多个位置,最好是粉碎信息并从头开始重新构建XML:

DECLARE @q XML=
N'<Question>
    <Choice ID="1">
        <Value>Choice A</Value>
    </Choice>
    <Choice ID="2">
        <Value>Choice B</Value>
    </Choice>
    <Choice ID="3">
        <Value>Choice C</Value>
    </Choice>
    <Choice ID="4">
        <Value>Choice D</Value>
    </Choice>
    <Choice ID="5">
        <Value>Choice E</Value>
    </Choice>
</Question>';

DECLARE @r XML=
N'<Response>
    <Question>
        <Value>Choice B</Value>
        <Value>Choice C</Value>
    </Question>
</Response>';

WITH QuestionCTE AS
(
    SELECT c.value('@ID','int') AS qID
          ,c.value('Value[1]','nvarchar(max)') AS qVal
    FROM @q.nodes('Question/Choice') AS A(c)
)
,ResponseCTE AS
(
    SELECT r.value('.','nvarchar(max)') AS rVal
    FROM @r.nodes('Response/Question/Value') AS A(r)
)
SELECT 
(
    SELECT q.qID AS [Value/@ID]
          ,q.qVal AS [Value] 
    FROM ResponseCTE AS r
    LEFT JOIN QuestionCTE AS q ON r.rVal=q.qVal 
    FOR XML PATH(''),TYPE
)
FOR XML PATH('Question'),ROOT('Response')

You can convert the XML to tables (question & response) and then link on the value. 您可以将XML转换为表(问题和响应),然后链接值。 You then look up the ID from the question table. 然后,您可以从问题表中查找ID。 Example: 例:


DECLARE @xml_q XML = N'
<Question>
    <Choice ID="1">
        <Value>Choice A</Value>
    </Choice>
    <Choice ID="2">
        <Value>Choice B</Value>
    </Choice>
    <Choice ID="3">
        <Value>Choice C</Value>
    </Choice>
    <Choice ID="4">
        <Value>Choice D</Value>
    </Choice>
    <Choice ID="5">
        <Value>Choice E</Value>
    </Choice>
</Question>';

DECLARE @xml_r XML = N'
<Response>
    <Question>
        <Value>Choice B</Value>
        <Value>Choice C</Value>
    </Question>
</Response>';

;WITH q_id AS (
    SELECT
        n.c.value('(./Value)[1]','NVARCHAR(128)') AS value,
        n.c.value('@ID','INT') AS id 
    FROM
        @xml_q.nodes('//Choice') AS n(c)
),
r_v AS (
    SELECT
        n.c.value('(.)[1]','NVARCHAR(128)') AS value
    FROM
        @xml_r.nodes('//Value') AS n(c)
)
SELECT 
    (
        SELECT
            q_id.id AS "Value/@ID",
            r_v.value AS "Value"
        FROM 
            r_v 
            INNER JOIN q_id ON 
                q_id.value=r_v.value
        FOR
            XML PATH(''), TYPE
    )
FOR 
    XML PATH('Question'), ROOT('Response');

Will give the response: 会给出回应:

<Response>
  <Question>
    <Value ID="2">Choice B</Value>
    <Value ID="3">Choice C</Value>
  </Question>
</Response>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM