Измените XML в SQL server, чтобы добавить корневой узел
-
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')
Посмотрите книги в Интернете для получения более подробной информации:
Не могли бы вы просто добавить " / " в качестве фиксированного текста в вашем выборе?Что -то вроде:
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)
Марк