Измените XML в SQL-сервере, чтобы добавить корневой узел - PullRequest
4 голосов
/ 08 марта 2009

Чтобы вначале дать некоторое представление об этой проблеме, я переписываю некоторый код, который в настоящее время проходит через некоторый xml, вставляя в таблицу в конце каждого цикла - заменяя один sp, который принимает параметр xml и выполняет вставьте за один раз, «измельчая» xml в таблицу.

Основное удаление было успешно выполнено, но в настоящее время один из столбцов используется для хранения всего узла. Я был в состоянии обработать запрос, необходимый для этого (почти), но он пропускает корневую часть узла. Я пришел к выводу, что мой запрос настолько хорош, насколько я могу его получить, и я ищу способ сделать оператор обновления, чтобы вернуть туда корневой узел.

Так что мой xml имеет форму;

<xml>
<Items>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
<Item>
    <node1>...</node1><node2>..<node2>.....<noden>...<noden>
<Item>
......
<Items>
</xml>

Таким образом, основное измельчение помещает значение из узла 1 в столбец 1, узел 2 в столбец 2 и т. Д. Оператор вставки выглядит примерно так;

INSERT INTO mytable col1, col2,...etc.....,wholenodecolumn
Select  
doc.col.value('node1[1]', 'int') column1,
doc.col.value('node2[1]', 'varchar(50)') column2,
....etc......,
doc.col.query('*')--this is the query for getting the whole node
FROM @xml.nodes('//Items/Item') doc(col)

XML, который заканчивается в wholenodecolumn, имеет форму;

<node1>...</node1><node2>..<node2>.....<noden>...<noden>

но мне нужно, чтобы он был в форме

<Item><node1>...</node1><node2>..<node2>.....<noden>...<noden></Item>

Существует существующий код (в значительной степени), который зависит от правильной формы XML-кода в этом столбце.

Так может кто-то может увидеть, как изменить doc.col.query('*'), чтобы получить желаемый результат?

В любом случае, я отказался от изменения запроса и попытался придумать другие способы достижения конечного результата. Сейчас я смотрю на обновление после вставки, что-то вроде;

update mytable set wholenodecolumn.modify('insert <Item> as first before * ')

Если бы я мог сделать это вместе с

 .modify('insert </Item> as last after * ')  

это было бы хорошо, но делать по 1 за раз не вариант, так как XML тогда недействителен

XQuery [mytable.wholenodecolumn.modify()]: Expected end tag 'Item'  

и делая оба вместе, я не знаю, возможно ли это, но я пробовал различный синтаксис и не могу приступить к работе.

Любые другие подходы к проблеме также с благодарностью получили

Ответы [ 3 ]

8 голосов
/ 09 марта 2009

Полагаю, вы можете указать имя корневого узла, используя предложение FOR.

Например:

select top 1 *
from HumanResources.Department
for XML AUTO, ROOT('RootNodeName')

Взгляните на книги в Интернете для более подробной информации:

http://msdn.microsoft.com/en-us/library/ms190922.aspx

6 голосов
/ 09 марта 2009

Отвечая на мой вопрос здесь! - это следует из комментариев к одному из других попыток ответов, где я сказал:

Я сейчас ищу FLWOR Конструкции Xquery в запросе.
col.query('for $item in * return <Item> {$item} </item>') почти там, но расставляет каждый узел, а не вокруг всех узлы

Я был почти там с синтаксисом, небольшая настройка дала мне то, что мне нужно;

doc.col.query('<Item> { for $item in * return $item } </item>'

Спасибо всем, кто помог. У меня сейчас есть другие связанные вопросы, но я опубликую их как отдельные вопросы

0 голосов
/ 09 марта 2009

Не могли бы вы просто добавить '' / '' в качестве фиксированного текста в ваш выбор? Что-то вроде:

Select  
  '<Item>',
  doc.col.value('node1[1]', 'int') column1,
  doc.col.value('node2[1]', 'varchar(50)') column2,
  ....etc......,
  doc.col.query('*'),
  '</Item>'      --this is the query for getting the whole node
FROM @xml.nodes('//Items/Item') doc(col)

Марк

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...