#xml #sql-server-2008 #types #temp-tables
#xml #sql-server-2008 #типы #временные таблицы
Вопрос:
У меня есть таблица с идентификатором (тип int) и большой двоичный объект XML-данных (1 столбец типа XML). У меня есть 10 строк в таблице, и мне нужно обновить каждый XML-двоичный объект / строку отдельно. Есть ли способ сделать это:
Вместо:
--Works ok to update XML by explicitly entering XML, or one-by-one:
declare @XMLNODE table (id int identity, doc xml)
insert @XMLNODE (doc) values (
'
<Root>
<Elements>
<Items>
<OldItem>
<ID>1</ID>
<Show Pointer="yes" />
<Display Pointer="Display">
<Detail1>some Details</Detail1>
</DisplayDetails>
</OldItem>
</Items>
</Elements>
</Root>'
)
--This is just an XML variable to get the output, but not related to the ID in table:
DECLARE @XMLOutput XML
SELECT @XMLOutput = (
SELECT a.value('(ID)[1]','int') as ID,
a.value('(Show/@Pointer)[1]', 'varchar(5)') AS ShowItem,
a.value('Display[1]/@Pointer[1]="Display"', 'varchar(10)') as DisplayDetails, -- Set to 'true' or 'false'
a.value('DisplayDetails[1][@Pointer[1]="Display"]/Detail1[1]', 'varchar(max)') as Detail1
FROM @XMLNODE t
cross apply
t.doc.nodes('//OldItem') x(a)
FOR XML PATH ('Items'),
ROOT('Elements')
)
Вместо этого я хочу сделать что-то вроде этого:
Declare @tempTable table(ID int not null, XMLData xml)
INSERT INTO @tempTable
SELECT OriginalTable.ID,
(--Perform above XML modification per row for each ID and put into a new table)
—Сделайте это для каждого идентификатора, чтобы заполнить @TempTable идентификатором, XML не просто возвращает XML.
Есть идеи по тому, как заставить это работать (возможно ли это даже с использованием курсора).
Комментарии:
1. могу ли я по-прежнему использовать вышеупомянутый подход или мне нужно изменить XML напрямую с помощью .modify() ?? Если да, может ли кто-нибудь указать мне на хороший пример — кроме ссылок msdn..
Ответ №1:
Вот упрощенный пример того, как вы можете обновить столбец XML.
-- Table that holds the XML
declare @T table(ID int, XMLCol xml)
-- Add sample data
insert into @T values (1, '<root><val1>1</val1><val2>2</val2></root>')
insert into @T values (2, '<root><val1>10</val1><val2>20</val2></root>')
-- The cte takes the values out of the
-- XML column in the table and modifies them
;with cte as
(
select
T.ID,
n.r.value('val1[1]', 'int') 1 as val1,
n.r.value('val2[1]', 'int') 2 as val2
from @T as T
cross apply
T.XMLCol.nodes('/root') as n(r)
)
-- Update the XMLCol with the new XML
update T
set XMLCol = N.XMLCol
from @T as T
inner join cte as C
on T.ID = C.ID
cross apply -- Here is the new XML constructed with xml path('')
(select C.val1, C.val2
for xml path('root'), type) as N(XMLCol)
Table @T перед изменением
ID XMLCol
----------- ---------------------------------------------
1 <root><val1>1</val1><val2>2</val2></root>
2 <root><val1>10</val1><val2>20</val2></root>
Table @T после изменения
ID XMLCol
----------- ----------------------------------------------
1 <root><val1>2</val1><val2>4</val2></root>
2 <root><val1>11</val1><val2>22</val2></root>