Обновление узла XML с преобразованием в SQL Server 2005 - PullRequest
4 голосов
/ 05 декабря 2011

У меня есть столбец, который содержит данные XML, но имеет тип TEXT, а не тип XML.(Я должен оставить это так по другой причине).

В основном мне нужно сначала преобразовать его в NText, а затем в XML.Единственная проблема - мой текущий формат, который работает для выбора значения узла, не работает для его обновления.

Сообщение об ошибке: Неверный синтаксис рядом с ключевым словом «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 Ответ

2 голосов
/ 06 декабря 2011

Возможно, есть веская причина для хранения XML в [n]varchar(max). Если вы хотите сохранить только XML, это нормально, но если вы хотите изменить части XML с помощью TSQL или если вам нужно запросить XML для значений или использовать значения узла / атрибута в предложении where, вам следует переключиться на XML, где Вы можете извлечь выгоду из индексов данных и пропустить преобразования типов. Поскольку text устарела, вы должны по крайней мере рассмотреть возможность переключения типа данных на [n]varchar(max)

Если бы у вас были данные в столбце XML, вы бы использовали XML DML для изменения XML. В вашем случае вы должны использовать заменить значение следующим образом.

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. Обновите XML, используя replace value of.
  4. Применить изменения обратно к tbl_Module_RequestForms_Items.

Примерно так: я предполагаю, что ID является первичным ключом для tbl_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
...