在SQL Server 2005中使用转换更新XML节点

时间:2011-12-05 16:55:09

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

我有一个包含XML数据的列,但它是TEXT类型而不是XML类型。 (由于其他原因,我不得不这样做。)

基本上我需要先将其转换为NText然后再转换为XML。唯一的问题是我当前用于选择Node值的格式无法更新它。

错误消息: 关键字“AS”附近的语法不正确。

UPDATE tbl_Module_RequestForms_Items
 SET CAST(CAST(TicorOregon..tbl_Module_RequestForms_Items.XML AS NTEXT) AS XML).value('(//Record/Submitted)[1]', 'NVARCHAR(max)') = 'True'
 WHERE CAST(CAST(TicorOregon..tbl_Module_RequestForms_Items.XML AS NTEXT) AS XML).value('(//Record/Submitted)[1]', 'NVARCHAR(max)') <> 'True'

XML数据:

 <Record>
   <Submitted>False</Submitted>
 </Record>

1 个答案:

答案 0 :(得分:2)

可能有正当理由将XML存储在[n]varchar(max)中。如果您只想存储XML,那么完全可以,但是如果您想使用TSQL修改XML的一部分,或者如果您需要在XML子句中查询值或在where子句中使用节点/属性值,则应切换到XML您可以从数据索引中受益,并跳过类型转换。由于不推荐text,您至少应考虑将数据类型切换为[n]varchar(max)

如果您在XML列中拥有数据,则可以使用XML DML来修改XML。在你的情况下,你会像这样使用replace value of

update tbl_Module_RequestForms_Items
set XMLData.modify('replace value of (/Record/Submitted/text())[1] with "True"')
where XMLData.value('(/Record/Submitted)[1]', 'bit') = 0

如果没有不可能的XML数据类型,则必须提取整个XML文档,修改它,然后使用修改后的XML文档更新表。

您当然可以使用某种客户端开发工具来实现这一点,但在TSQL中也可以这样做。

  1. 使用来自tbl_Module_RequestForms_Items的主键和XMLData列声明表变量,但作为数据类型XML。
  2. 将行从tbl_Module_RequestForms_Items复制到应更新的表变量。
  3. 使用replace value of更新XML。
  4. 将更改应用回tbl_Module_RequestForms_Items
  5. 我认为IDtbl_Module_RequestForms_Items的主键,并且您的XML数据位于XMLData列中,这样的话就是这样:

    declare @T table
    (
      ID int primary key,
      XMLData xml
    )
    
    insert into @T 
    select M.ID,
           M.XMLData
    from tbl_Module_RequestForms_Items as M
    where cast(cast(XMLData as nvarchar(max)) as xml).value('(/Record/Submitted)[1]', 'bit') = 0
    
    update @T
    set XMLData.modify('replace value of (/Record/Submitted/text())[1] with "True"')
    
    update M
    set XMLData = cast(T.XMLData as nvarchar(max))
    from tbl_Module_RequestForms_Items as M
      inner join @T as T
        on M.ID = T.ID