SQL Server XML-修改多个元素

时间:2019-04-22 15:21:22

标签: sql-server xml xpath xquery-sql

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

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

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

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

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

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

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

1 个答案:

答案 0 :(得分:0)

在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>