在SQL中更新(替换partcial值)XML列

时间:2016-08-11 05:33:22

标签: sql sql-server xml tsql xquery-sql

我的表中有一个XML列,我希望用新文本替换该列中出现的特定文本。这是xml结构,

<Story>
 <StoryNonText>
  <NonText>
   <ImageID>1</ImageID>
   <Src>http://staging.xyz.com/FolderName/1.png</Src>
  </NonText>
  <NonText>
   <ImageID>2</ImageID>
   <Src>http://staging.xyz.com/FolderName/2.png</Src>
  </NonText>
 </StoryNonText>
</Story> 

在上面的XML中,我想将 http://staging.xyz.com/ 的所有<Src>值替换为 http://production.xyz.com/ 。请指导我如何做到这一点!

3 个答案:

答案 0 :(得分:3)

在几个XML函数的帮助下,您可以循环执行此操作。 循环是必要的,因为replace value of一次只能替换一个值。此代码假定URL首先位于节点中,而不是嵌入在任何地方的文本中。

declare @T table(X xml);

insert into @T(X) values('<Story>
 <StoryNonText>
  <NonText>
   <ImageID>1</ImageID>
   <Src>http://staging.xyz.com/FolderName/1.png</Src>
  </NonText>
  <NonText>
   <ImageID>2</ImageID>
   <Src>http://staging.xyz.com/FolderName/2.png</Src>
  </NonText>
 </StoryNonText>
</Story> ');

declare @FromURL nvarchar(100);
declare @ToURL nvarchar(100);

set @FromURL = 'http://staging.xyz.com/';
set @ToURL = 'http://production.xyz.com/';

while 1 = 1
begin
  update @T
  set X.modify('replace value of (//*/text()[contains(., sql:variable("@FromURL"))])[1] 
               with concat(sql:variable("@ToURL"), substring((//*/text()[contains(., sql:variable("@FromURL"))])[1], string-length(sql:variable("@FromURL"))+1))')
  where X.exist('//*/text()[contains(., sql:variable("@FromURL"))]') = 1;

  if @@rowcount = 0
    break;
end;

select *
from @T

replace value of (XML DML)
concat Function (XQuery)
contains Function (XQuery)
string-length Function (XQuery)
sql:variable() Function (XQuery)

答案 1 :(得分:2)

您可以使用替换()功能,如下所示:

Update TableName
SET
ColumnName=replace(CAST(ColumnName AS VARCHAR(8000)),'<Src>http://staging.xyz.com/','<Src>http://production.xyz.com/')

答案 2 :(得分:0)

有很多方法可以做到这一点。

第一种方法是添加WHILE循环。在循环内,搜索(CHARINDEX)第一个标记和第一个标记的位置。然后,知道开始和结束位置,替换值。然后在下一次迭代中再次搜索,但在CHARINDEX()函数

中更改起始位置

第二种方法是使用SELECT ... FROM OPENXML + EXEC sp_xml_preparedocument