Dans SQL Server, puis-je insérer plusieurs nœuds dans XML à partir d'une table?
-
02-07-2019 - |
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.
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
- http://msdn2.microsoft.com/en -us / library / ms178107 (SQL.90) .aspx
- http://msdn2.microsoft.com/fr -us / library / ms189885 (SQL.90) .aspx
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