SQL Server 2008 XML使用其他元素值中的文本替换元素值

时间:2012-01-15 21:14:56

标签: xml sql-server-2008

使用下表:

CREATE TABLE [dbo].[GDB_ITEMS](
    [ObjectID] [int] NOT NULL,
    [UUID] [uniqueidentifier] NOT NULL,
    [Type] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](226) NULL,
    [PhysicalName] [nvarchar](226) NULL,
    [Path] [nvarchar](512) NULL,
    [Url] [nvarchar](255) NULL,
    [Properties] [int] NULL,
    [Defaults] [varbinary](max) NULL,
    [DatasetSubtype1] [int] NULL,
    [DatasetSubtype2] [int] NULL,
    [DatasetInfo1] [nvarchar](255) NULL,
    [DatasetInfo2] [nvarchar](255) NULL,
    [Definition] [xml] NULL,
    [Documentation] [xml] NULL,
    [ItemInfo] [xml] NULL,
    [Shape] [geometry] NULL,
 CONSTRAINT [R2_pk] PRIMARY KEY CLUSTERED 
(
    [ObjectID] ASC
)

xml列documentation包含此元素组1:

<spdom>
  <bounding>
    <westbc>-84.007769</westbc>
    <eastbc>-83.037582</eastbc>
    <northbc>35.790660</northbc>
    <southbc>35.418718</southbc>
  </bounding>
</spdom>

和这个元素组2:

<GeoBndBox esriExtentType="search">
  <westBL Sync="TRUE">-84.024010</westBL>
  <eastBL Sync="TRUE">-82.992641</eastBL>
  <northBL Sync="TRUE">35.845552</northBL>
  <southBL Sync="TRUE">35.417139</southBL>
  <exTypeCode Sync="TRUE">1</exTypeCode>
</GeoBndBox>

我想以编程方式执行的操作是将group1中的值替换为组2中的值。例如,westbcwestBL是相同的定义,所以我想要用-84.024010替换-84.007769。尝试在gdb_items中的几千条记录中执行此操作,每个记录在该元素组中具有不同的文本值。谢谢!

1 个答案:

答案 0 :(得分:1)

您应该使用replace value of (XML DML)

用于将westbc的值替换为10的语法如下所示。

update GDB_ITEMS
set Documentation.modify(
  'replace value of (//spdom/bounding/westbc/text())[1] with "10"')

为了掌握你需要的价值,你可以使用这样的东西:

select Documentation.value('(//GeoBndBox/westBL)[1]', 'varchar(20)')
from GDB_ITEMS

将这两者放在一个更新声明中。

update T
set Documentation.modify(
  'replace value of (//spdom/bounding/westbc/text())[1] 
   with sql:column("S.Value")')
from GDB_ITEMS as T
  cross apply (select T.Documentation.value('(//GeoBndBox/westBL)[1]', 
                                            'varchar(20)')) as S(Value) 

不可能一次替换多个节点中的值,因此必须为每个节点重复此操作。您可以使用具有源节点名称和目标节点名称的映射表在循环中完成此操作。

declare @Map table
(
  ID int identity primary key,
  TargetNode varchar(7),  
  SourceNode varchar(7)
)

insert into @Map values
('westbc',  'westBL'),
('eastbc',  'eastBL'),
('northbc', 'northBL'),
('southbc', 'southBL')

declare @ID int = 1

while @ID <= 4
begin
  update T 
  set Documentation.modify('replace value of 
                              (//spdom/bounding/*[local-name(.)=sql:column("M.TargetNode")]/text())[1] 
                            with sql:column("S.Value")')
  from GDB_ITEMS as T
    cross apply (select TargetNode, SourceNode from @Map where ID = @ID) as M
    cross apply (select Documentation.value('(//GeoBndBox/*[local-name(.)=sql:column("M.SourceNode")])[1]', 'varchar(20)')) as S(Value)

  set @ID += 1
end  

在此尝试:http://data.stackexchange.com/stackoverflow/query/59329/new