openxml, где пункт для обновления sql - PullRequest
2 голосов
/ 23 февраля 2011

Это мой xml

<root>
<children>
 <child id = "1">
  <description>This is child 1</description>
 </child>
 <child id = "2">
    <description>This is child 2</description>
 </child>
 <child id = "3">
    <description>This is child 3</description>
 </child>
</children>
</root>

Я пытаюсь обновить таблицу с именем Child, в которой есть столбцы "ID" и "Description".В таблице уже есть значения столбца ID, но описание пустое.Мне нужно обновить это описание по идентификатору из указанного выше xml-файла.

Я попытался сделать OPENXML со значением флага 2 (элементно-ориентированным) и смог получить все описания.Но я не знаю, как получить описания на основе значений идентификатора, используя выражение where в OPENXML.

База данных, которую я использую, - это SQL Server 2008.
(Также будет работать OPENXML для SQL Server 2005?)

Вот что я пытался сделать:

DECLARE @idoc int DECLARE @doc xml

select @doc= c from openrowset(bulk 'C:\Test.xml',single_blob) as temp(c)
exec sp_xml_preparedocument @idoc output, @doc 

SELECT * FROM OPENXML (@idoc, '/root/children/child', 2)
  WITH (summary  varchar(1000)) descr 
EXEC sp_xml_removedocument @idoc

Заранее спасибо Ник

ps: Структура XML не может быть изменена.Мне нужно обойти это ограничение.

1 Ответ

7 голосов
/ 23 февраля 2011

Если вы работаете на SQL Server 2005 или более поздней версии и XML хранится в переменной с именем @input, вы можете попробовать это:

declare @input XML 

set @input = '<root>
<children>
 <child id="1">
  <description>This is child 1</description>
 </child>
 <child id="2">
    <description>This is child 2</description>
 </child>
 <child id="3">
    <description>This is child 3</description>
 </child>
</children>
</root>'

;with GrabXML AS
(
    select
        child.value('@id', 'int') as 'ID',
        child.value('(description)[1]', 'varchar(50)') as 'Description'
    from
        @input.nodes('/root/children/child') as n(Child)
)
update dbo.Child
set description = g.Description
from GrabXML g
where dbo.Child.ID = g.ID

GrabXML общее табличное выражение (CTE) анализирует и выравнивает XML по строкам и столбцам, и следующий оператор UPDATE использует эти строки / столбцы для обновления существующей таблицы.

Обновление: есть две возможные проблемные точкиесли ваши строки длиннее, чем вы ожидаете:

во-первых, вам может потребоваться увеличить длину при преобразовании из XML:

select
   child.value('@id', 'int') as 'ID',
   child.value('(description)[1]', 'varchar(999)') as 'Description'

, а во-вторых, вам нужно проверить, какую длинуСтолбец в таблице dbo.Child является усеченной длиной строки, извлеченной из XML, чтобы она не превышала длину столбца базы данных:

update dbo.Child
set description = SUBSTRING(g.Description, 1, 575)

Здесь необходимо извлечь не более столько символов из строки g.Description, сколько позволяет столбец вашей базы данных dbo.Child.description.

...