更新,查找/替换xml字段

时间:2013-07-13 12:16:38

标签: sql sql-server tsql

我的数据库中有一个Page表。 让我们说简单,它有两列; title和xmlData 它的标题类似于“我的例子” 我有一个xml字段,如下所示:

<MA>
  <A>
    <URL>my-example-</URL>
    <id>5</id>
    </A>
</MA>
  1. 我正在尝试查找替换最后有“ - ”的任何网址,并删除唯一的最后一个“ - ”(如果存在)

  2. 并删除尾随空格(如果有一个,则为标题)

  3. 我可以通过执行

    来获取需要更改的行
    select * from Pages
    where title like '% '
    

    (有一些连接和东西,但基本上就是这样)

2 个答案:

答案 0 :(得分:1)

这将替换每行的一次URL。通过示例XML的外观,每行只有一个URL。

with C1 as
(
  select xmlData,
         xmlData.value('(/MA/A/URL/text())[1]', 'nvarchar(500)') as URL
  from Pages
),
C2 as
(
  select xmlData,
         URL,
         left(URL, len(URL) - 1) as URL2
  from C1
  where right(URL, 1) = '-'
)
update C2 
set xmlData.modify('replace value of (/MA/A/URL/text())[1] 
                    with sql:column("C2.URL2")')

在CTE C1中提取URL值 从URL中删除最后一个' - ',并将其放在CT2 C2中的URL2中。同时删除不需要更新的行 使用modify() Method (xml Data Type)

更新XML

这是另一个版本,它在查询的XML部分完成了工作。

update Pages
set xmlData.modify('replace value of (/MA/A/URL/text())[1] 
                    with fn:substring((/MA/A/URL/text())[1], 1, fn:string-length((/MA/A/URL/text())[1])-1)')
where xmlData.exist('/MA/A/URL[fn:substring(text()[1], fn:string-length(text()[1]), 1) = "-"]') = 1

一次只能更新一个节点,因此如果您在一行中有多个URL,则必须将上面的代码放在循环中,并且只要有更新内容就进行更新。您可以使用@@ROWCOUNT检查更新是否确实更新了任何内容并重做更新,直到@@ROWCOUNT = 0

答案 1 :(得分:0)

您可以使用CHARINDEX函数来检查是否存在字符' - '等等,您可以使用SUBSTIRNG函数仅抓取部分来替换您的文本。

示例:

declare @a varchar(100)
set @a = 'HI, TODAY IS A - BEAUTIFUL DAY'

select 
    case
        when charindex('-',@a) >= 0 then
        substring(@a, 0, charindex('-',@a)-1) + 
        substring(@a, charindex('-', @a) + 1, 100)
        else @a
    end