Могу ли я в SQL Server вставить несколько узлов в XML из таблицы?
-
02-07-2019 - |
Вопрос
Я хочу сгенерировать XML в хранимой процедуре на основе данных в таблице.
Следующая вставка позволяет мне добавить много узлов, но они должны быть жестко запрограммированы или использовать переменные (sql:variable):
SET @MyXml.modify('
insert
<myNode>
{sql:variable("@MyVariable")}
</myNode>
into (/root[1]) ')
Таким образом, я мог бы просмотреть каждую запись в своей таблице, поместить нужные мне значения в переменные и выполнить приведенный выше оператор.
Но есть ли способ сделать это, просто объединив оператор select и избежав цикла?
Редактировать я использовал SELECT FOR XML
раньше делал подобные вещи, но мне всегда трудно читать при работе с иерархией данных из нескольких таблиц.Я надеялся, что будет что-то с использованием modify
где сгенерированный XML является более явным и более управляемым.
Решение
Попытался ли ты гнездование ДЛЯ скалярных функций XML PATH?С помощью техники вложения вы можете разбить свой SQL на легко управляемые/читабельные элементарные части.
Отказ от ответственности:следующее, хотя и адаптировано из рабочего примера, само по себе не было протестировано в буквальном смысле
Некоторые справочные ссылки для широкой аудитории
- http://msdn2.microsoft.com/en-us/library/ms178107(SQL.90).aspx
- http://msdn2.microsoft.com/en-us/library/ms189885(SQL.90).aspx
Самый простой пример вложенного узла самого низкого уровня.
Рассмотрим следующий вызов
DECLARE @NestedInput_SpecificDogNameId int
SET @NestedInput_SpecificDogNameId = 99
SELECT [dbo].[udfGetLowestLevelNestedNode_SpecificDogName]
(@NestedInput_SpecificDogNameId)
Допустим, udfGetLowestLevelNestedNode_SpecificDogName был написан без предложения FOR XML PATH, а для @NestedInput_SpecificDogName = 99 он возвращает одну запись набора строк:
@SpecificDogNameId DogName 99 Astro
Но с предложением FOR XML PATH
CREATE FUNCTION dbo.udfGetLowestLevelNestedNode_SpecificDogName
(
@NestedInput_SpecificDogNameId
)
RETURNS XML
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar XML
-- Add the T-SQL statements to compute the return value here
SET @ResultVar =
(
SELECT
@SpecificDogNameId as "@SpecificDogNameId",
t.DogName
FROM tblDogs t
FOR XML PATH('Dog')
)
-- Return the result of the function
RETURN @ResultVar
END
определяемая пользователем функция создает следующий XML-код (знаки @ приводят к тому, что полеSpecificDogNameId возвращается в качестве атрибута)
<Dog SpecificDogNameId=99>Astro</Dog>
Вложение пользовательских функций типа XML
Пользовательские функции, такие как приведенная выше udfGetLowestLevelNestedNode_SpecificDogName, могут быть вложенными, чтобы предоставить мощный метод создания сложного XML.
Например, функция
CREATE FUNCTION [dbo].[udfGetDogCollectionNode]()
RETURNS XML
AS
BEGIN
-- Declare the return variable here
DECLARE @ResultVar XML
-- Add the T-SQL statements to compute the return value here
SET @ResultVar =
(
SELECT
[dbo].[udfGetLowestLevelNestedNode_SpecificDogName]
(t.SpecificDogNameId)
FROM tblDogs t
FOR XML PATH('DogCollection') ELEMENTS
)
-- Return the result of the function
RETURN @ResultVar
END
при вызове как
SELECT [dbo].[udfGetDogCollectionNode]()
может создать сложный узел XML (при наличии соответствующих базовых данных)
<DogCollection>
<Dog SpecificDogNameId="88">Dino</Dog>
<Dog SpecificDogNameId="99">Astro</Dog>
</DogCollection>
Отсюда вы можете продолжать двигаться вверх по вложенному дереву, чтобы построить настолько сложную структуру XML, насколько захотите.
CREATE FUNCTION [dbo].[udfGetAnimalCollectionNode]()
RETURNS XML
AS
BEGIN
DECLARE @ResultVar XML
SET @ResultVar =
(
SELECT
dbo.udfGetDogCollectionNode(),
dbo.udfGetCatCollectionNode()
FOR XML PATH('AnimalCollection'), ELEMENTS XSINIL
)
RETURN @ResultVar
END
при вызове как
SELECT [dbo].[udfGetAnimalCollectionNode]()
udf может создать более сложный узел XML (с учетом соответствующих базовых данных)
<AnimalCollection>
<DogCollection>
<Dog SpecificDogNameId="88">Dino</Dog>
<Dog SpecificDogNameId="99">Astro</Dog>
</DogCollection>
<CatCollection>
<Cat SpecificCatNameId="11">Sylvester</Cat>
<Cat SpecificCatNameId="22">Tom</Cat>
<Cat SpecificCatNameId="33">Felix</Cat>
</CatCollection>
</AnimalCollection>
Другие советы
Можете ли вы рассказать немного больше о том, что именно вы планируете делать?Это просто генерирует данные XML на основе содержимого таблицы или добавление некоторых данных из таблицы в существующую структуру XML?
Есть отличная серия статей по теме XML в SQLServer, написанной Джейкобом Себастьяном, она начинается с основы генерации XML из данных таблицы
Используйте sql:column вместо sql:variable.Подробную информацию вы можете найти здесь: http://msdn.microsoft.com/en-us/library/ms191214.aspx