【问题标题】:SQL: Use modify function to iterate on xml nodes or How to insert or modify nodes recursivelySQL:使用 modify 函数迭代 xml 节点或如何递归地插入或修改节点
【发布时间】:2023-03-10 15:55:02
【问题描述】:

我有一个xml,如下面的代码所示

我想遍历每个节点并在每个 TextReadingName 节点之后插入一个节点

DECLARE @XML XML =
N'<Steplist>
  <Step>
    <StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
    <Rank>1</Rank>
    <IsComplete>false</IsComplete>
    <TextReadingName>bug-8588_Updated3</TextReadingName>     
  </Step>
  <Step>
    <StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
    <Rank>2</Rank>
    <TextReadingName>reading1</TextReadingName>
  </Step>
</Steplist>';



--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM   @xml.nodes('/Steplist/Step') x(XmlCol)  

这就是我希望我的新 xml 的外观

N'<Steplist>
      <Step>
        <StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
        <Rank>1</Rank>
        <IsComplete>false</IsComplete>
        <TextReadingName>bug-8588_Updated3</TextReadingName>    
      <TextReadingId>1</TextReadingId>   
      </Step>
      <Step>
        <StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
        <Rank>2</Rank>
        <TextReadingName>reading1</TextReadingName>
      <TextReadingId>2</TextReadingId> 
      </Step>
    </Steplist>';

我可以选择如下所示的节点,但无法遍历每个节点并修改数据

--SELECT x.XmlCol.value('(StepId)[1]', 'nvarchar(max)') as StepId
--FROM   @xml.nodes('/Steplist/Step') x(XmlCol) 

我正在寻找与上面相同的功能,但用于插入节点

这就是我希望我的新 xml 在 TextReading 名称之后使用名为 TextReadingId 的新节点的方式

N'<Steplist>
      <Step>
        <StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
        <Rank>1</Rank>
        <IsComplete>false</IsComplete>
        <TextReadingName>bug-8588_Updated3</TextReadingName>    
      <TextReadingId>1</TextReadingId>   
      </Step>
      <Step>
        <StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
        <Rank>2</Rank>
        <TextReadingName>reading1</TextReadingName>
      <TextReadingId>2</TextReadingId> 
      </Step>
    </Steplist>';

【问题讨论】:

    标签: sql xml xquery xquery-sql


    【解决方案1】:

    您可以将modifyinsert 一起使用,但主要缺点似乎是SQL server 只允许insert 进入单个节点,我无法将它与FLOWR 表达式组合,所以我不得不使用一个 SQL WHILE 循环来执行各种modify 调用:

    DECLARE @XML XML =
    N'<Steplist>
      <Step>
        <StepId>e36a3450-1c8f-44da-b4d0-58e5bfe2a987</StepId>
        <Rank>1</Rank>
        <IsComplete>false</IsComplete>
        <TextReadingName>bug-8588_Updated3</TextReadingName>     
      </Step>
      <Step>
        <StepId>4078c1b1-71ea-4578-ba61-d2f6a5126ba1</StepId>
        <Rank>2</Rank>
        <TextReadingName>reading1</TextReadingName>
      </Step>
    </Steplist>';
    
    BEGIN
    
    DECLARE @i int;
    
    SELECT @i = @XML.value('count(Steplist/Step)', 'int');
    
    WHILE @i > 0
      BEGIN
    
        SET @XML.modify('insert <TextReadingId>{sql:variable("@i")}</TextReadingId> as last into (/Steplist/Step[sql:variable("@i")])[1]');
    
        SET @i = @i - 1;
      END
    END
    SELECT @XML;
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2023-01-03
    • 1970-01-01
    • 2011-06-01
    相关资源
    最近更新 更多