Могу ли я в SQL Server вставить несколько узлов в XML из таблицы?

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

Вопрос

Я хочу сгенерировать XML в хранимой процедуре на основе данных в таблице.

Следующая вставка позволяет мне добавить много узлов, но они должны быть жестко запрограммированы или использовать переменные (sql:variable):

SET @MyXml.modify('
      insert
         <myNode>
            {sql:variable("@MyVariable")}
         </myNode>
      into (/root[1]) ') 

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

Но есть ли способ сделать это, просто объединив оператор select и избежав цикла?

Редактировать я использовал SELECT FOR XML раньше делал подобные вещи, но мне всегда трудно читать при работе с иерархией данных из нескольких таблиц.Я надеялся, что будет что-то с использованием modify где сгенерированный XML является более явным и более управляемым.

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

Решение

Попытался ли ты гнездование ДЛЯ скалярных функций XML PATH?С помощью техники вложения вы можете разбить свой SQL на легко управляемые/читабельные элементарные части.

Отказ от ответственности:следующее, хотя и адаптировано из рабочего примера, само по себе не было протестировано в буквальном смысле

Некоторые справочные ссылки для широкой аудитории

Самый простой пример вложенного узла самого низкого уровня.

Рассмотрим следующий вызов

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

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