Question

Je souhaite générer du code XML dans une procédure stockée en fonction des données d'un tableau.

L'insertion suivante me permet d'ajouter de nombreux nœuds, mais ils doivent être codés en dur ou utiliser des variables (sql: variable):

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

Je pourrais ainsi parcourir chaque enregistrement de ma table, placer les valeurs dont j'ai besoin dans des variables et exécuter l'instruction ci-dessus.

Mais y a-t-il un moyen de faire cela en combinant simplement avec une instruction select et en évitant la boucle?

Modifier J'ai déjà utilisé SELECT FOR XML pour effectuer des tâches similaires, mais je trouve toujours difficile à lire lorsque vous travaillez avec une hiérarchie de données provenant de plusieurs tables. J'espérais qu'il y aurait quelque chose utilisant modifier où le XML généré est plus explicite et plus contrôlable.

Était-ce utile?

La solution

Avez-vous essayé d'imbriquer des fonctions à valeur scalaire FOR XML PATH? Avec la technique d'imbrication, vous pouvez freiner votre SQL en éléments élémentaires très gérables / lisibles

Avertissement: le texte suivant, bien que adapté d'un exemple pratique, n'a pas encore été testé littéralement

Quelques liens de référence pour le grand public

Le plus simple, exemple de noeud imbriqué de niveau le plus bas

Considérez l'invocation suivante

DECLARE  @NestedInput_SpecificDogNameId int
SET @NestedInput_SpecificDogNameId = 99
SELECT [dbo].[udfGetLowestLevelNestedNode_SpecificDogName] 
(@NestedInput_SpecificDogNameId)

Supposons que udfGetLowestLevelNestedNode_SpecificDogName ait été écrit sans la clause FOR XML PATH et que, pour @NestedInput_SpecificDogName = 99, il renvoie l'enregistrement de jeu de lignes unique:

@SpecificDogNameId  DogName
99                  Astro

Mais avec la clause 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

la fonction définie par l'utilisateur génère le code XML suivant (les signes @ entraînent le renvoi du champ SpecificDogNameId en tant qu'attribut)

<Dog SpecificDogNameId=99>Astro</Dog>

Imbrication de fonctions de type XML définies par l'utilisateur

Les fonctions définies par l'utilisateur, telles que la fonction ci-dessus, udfGetLowestLevelNestedNode_SpecificDogName peuvent être imbriquées pour fournir une méthode puissante de production de code XML complexe.

Par exemple, la fonction

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

lorsqu'il est appelé en tant que

SELECT [dbo].[udfGetDogCollectionNode]()

peut produire le noeud XML complexe (en fonction des données sous-jacentes appropriées)

<DogCollection>
    <Dog SpecificDogNameId="88">Dino</Dog>
    <Dog SpecificDogNameId="99">Astro</Dog>
</DogCollection>

À partir de là, vous pouvez continuer à travailler dans l'arborescence imbriquée pour créer une structure XML aussi complexe que vous le souhaitez

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

lorsqu'il est appelé en tant que

SELECT [dbo].[udfGetAnimalCollectionNode]()

L'udf peut produire le nœud XML plus complexe (en fonction des données sous-jacentes appropriées)

<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>

Autres conseils

Pouvez-vous en dire un peu plus sur ce que vous comptez faire exactement? Est-ce simplement générer des données XML basées sur un contenu de la table ou ajouter des données de la table à une structure XML existante?

Il existe une grande série d'articles sur le sujet en XML dans SQLServer écrit par Jacob Sebastian, il commence par les bases de la génération de XML à partir des données contenues dans la table

Utilisez sql: column au lieu de sql: variable. Vous pouvez trouver des informations détaillées ici: http://msdn.microsoft.com/en -us / library / ms191214.aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top