En SQL Server, ¿puedo insertar múltiples nodos en XML desde una tabla?
-
02-07-2019 - |
Pregunta
Quiero generar algún XML en un procedimiento almacenado basado en datos en una tabla.
La siguiente inserción me permite agregar muchos nodos, pero tienen que estar codificados o usar variables (sql: variable):
SET @MyXml.modify('
insert
<myNode>
{sql:variable("@MyVariable")}
</myNode>
into (/root[1]) ')
Para poder recorrer cada registro de mi tabla, colocar los valores que necesito en las variables y ejecutar la declaración anterior.
Pero, ¿hay una manera en que pueda hacerlo simplemente combinando con una declaración de selección y evitando el bucle?
Editar He usado SELECT FOR XML
para hacer cosas similares antes, pero siempre me resulta difícil leer cuando se trabaja con una jerarquía de datos de varias tablas. Esperaba que hubiera algo usando el modificar
donde el XML generado sea más explícito y más controlable.
Solución
¿Has probado anidando para funciones escaladas de XML PATH? Con la técnica de anidación, puede romper su SQL en piezas elementales muy manejables / legibles
Descargo de responsabilidad: lo siguiente, aunque está adaptado de un ejemplo de trabajo, no se ha probado literalmente
Algunos enlaces de referencia para la audiencia general
- http://msdn2.microsoft.com/en -us / library / ms178107 (SQL.90) .aspx
- http://msdn2.microsoft.com/en -us / library / ms189885 (SQL.90) .aspx
El ejemplo de nodo anidado más simple y de nivel más bajo
Considera la siguiente invocación
DECLARE @NestedInput_SpecificDogNameId int
SET @NestedInput_SpecificDogNameId = 99
SELECT [dbo].[udfGetLowestLevelNestedNode_SpecificDogName]
(@NestedInput_SpecificDogNameId)
Digamos que se ha escrito udfGetLowestLevelNestedNode_SpecificDogName sin la cláusula FOR XML PATH, y para @NestedInput_SpecificDogName = 99 devuelve el único registro de conjunto de filas:
@SpecificDogNameId DogName 99 Astro
Pero con la cláusula 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 función definida por el usuario produce el siguiente XML (los signos @ hacen que el campo SpecificDogNameId se devuelva como un atributo)
<Dog SpecificDogNameId=99>Astro</Dog>
Anidando funciones definidas por el usuario de tipo XML
Las funciones definidas por el usuario, como el udfGetLowestLevelNestedNode_SpecificDogName anterior, se pueden anidar para proporcionar un método eficaz para producir XML complejo.
Por ejemplo, la función
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
cuando se invoca como
SELECT [dbo].[udfGetDogCollectionNode]()
podría producir el nodo XML complejo (dados los datos subyacentes apropiados)
<DogCollection>
<Dog SpecificDogNameId="88">Dino</Dog>
<Dog SpecificDogNameId="99">Astro</Dog>
</DogCollection>
Desde aquí, podría seguir trabajando hacia arriba en el árbol anidado para crear una estructura XML tan compleja como desee
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
cuando se invoca como
SELECT [dbo].[udfGetAnimalCollectionNode]()
el udf podría producir el nodo XML más complejo (dados los datos subyacentes apropiados)
<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>
Otros consejos
¿Puede contarnos un poco más sobre lo que planea hacer exactamente? ¿Se trata simplemente de generar datos XML basados ??en un contenido de la tabla? ¿O agregar algunos datos de la tabla a una estructura xml existente?
Hay gran serie de artículos sobre el tema en XML en SQLServer escrito por Jacob Sebastian, comienza con los conceptos básicos para generar XML a partir de los datos en la mesa
Use sql: column en lugar de sql: variable. Puede encontrar información detallada aquí: http://msdn.microsoft.com/en -us / library / ms191214.aspx