Измените XML в SQL server, чтобы добавить корневой узел

StackOverflow https://stackoverflow.com/questions/624206

  •  05-07-2019
  •  | 
  •  

Вопрос

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

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

Итак, мой 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>

Таким образом, базовое измельчение помещает значение из node1 в column1, node2 в column2 и т.д.Оператор insert выглядит примерно так;

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'  

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

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

Это было полезно?

Решение 2

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

  

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

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

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

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

Другие советы

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

Например:

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

Посмотрите книги в Интернете для получения более подробной информации:

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

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

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)

Марк

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top