【问题标题】:SQL Server XML - modify multiple elementsSQL Server XML - 修改多个元素
【发布时间】:2019-09-11 18:48:51
【问题描述】:

我有一个 SQL Server XML 列,其中包含如下数据:

<History>
   <Entry>
      .....
   </Entry>
   <Entry>
      .....
   </Entry>
</History>

我需要为每个 Entry 元素添加一个唯一标识符,给出以下结果:

<History>
  <Entry entryID="AAA">
      .....
   </Entry>
   <Entry entryID="BBB">
      .....
   </Entry>
</History>

我让它适用于第一次出现的 Entry 元素,但不知道如何将它应用于所有出现。另外,这个 entryID 是一个 GUID,我不知道如何为每一行生成一个新的。

这是我更新第一个元素的方法。

declare @eventId varchar(64)
set @eventId =  CONVERT(varchar(64),NEWID())
update Histories
       set XmlHistory.modify('
              insert attribute EntryID {sql:variable("@eventId")}
                     into (History/Entry)[1]
       ')
where HistoryID=285162

我也有查询选择需要这个属性但还没有它的元素。这给出了主键和我需要更新的元素。我无法获得用于元素数组索引的唯一元素标识符。

select h.id rowPK, m.c.query('.') theElement
from TheTable h
    cross apply h.XMLColumn.nodes('History/Entry[not(@EntryID)]') m(c)
where XMLColumn.exist('(History/Entry)')= 1

【问题讨论】:

    标签: sql-server xml xpath xquery-sql


    【解决方案1】:

    在 SQL Server 中操作 XML 可能非常困难,如果您有选择,任何其他选择!在将其作为 XML 加载到 Sql Server 之前,您应该应用唯一 ID。我能做的最好的是将 XML 分解为表变量,添加键,然后提取为 XML 流。我希望这会有所帮助...

    请注意,这确实会检查重复键,因此您需要处理该问题,并且您需要包含问题中未引用的任何其他节点或元素。

    declare @Histories table
    (
        HistoryID int,
        XmlHistory xml
    )
    
    insert into @Histories values (285162, '
    <History> 
      <Entry> 
        Entry 1
      </Entry> 
      <Entry> 
        Entry 2
      </Entry> 
      <Entry> 
        Entry 3
      </Entry> 
      <Entry> 
        Entry 4
      </Entry> 
    </History>');
    
    declare @tmp table 
    (
      EntryVal varchar(max),
      EntryGuid varchar(64)
    )
    
    insert into @tmp(EntryVal, EntryGuid)
    SELECT p1.value(N'.[1]','nvarchar(max)') AS EntryValue, CONVERT(varchar(64),NEWID())
    from   @Histories H1
    outer apply H1.XmlHistory.nodes(N'/History/Entry') AS A(p1)
    
    select EntryGuid as '@ID', EntryVal as "data()"
    from   @tmp
    for    XML PATH ('ENTRY'), root ('HISTORY');  
    

    输出应该是这样的

    <HISTORY>
      <ENTRY ID="1C5C9492-36C8-4E4E-9AE3-DF7E2F1C1948"> 
        Entry 1
      </ENTRY>
      <ENTRY ID="9AC4BB5D-C471-4C89-947B-8C17D2BD446C"> 
        Entry 2
      </ENTRY>
      <ENTRY ID="10A81C91-A58B-4846-A857-A14BFB7F9CB7"> 
        Entry 3
      </ENTRY>
      <ENTRY ID="0E65D134-37A2-489C-8C72-5BE52D08D7B1"> 
        Entry 4
      </ENTRY>
    </HISTORY>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-27
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      相关资源
      最近更新 更多