insert (XML DML)

Inserta uno o más nodos identificados por Expression1 como nodos secundarios o del mismo nivel que el nodo identificado por Expression2.

Sintaxis

insert 
      Expression1 (
                 {as first | as last} into | after | before
                                    Expression2
                )

Argumentos

  • Expression1
    Identifica uno o varios nodos que se van a insertar. Puede ser una instancia XML constante o una expresión XQuery. La expresión puede proporcionar un nodo, y también un nodo de texto, o una secuencia ordenada de nodos. No se puede resolver en el nodo raíz (/). Si la expresión da como resultado un valor o una secuencia de valores, los valores se insertan como un solo nodo de texto y cada valor de la secuencia se separa con un espacio. Si se especifican varios nodos como constante, los nodos se incluyen entre paréntesis y se separan mediante comas. No es posible insertar secuencias heterogéneas, como una secuencia de elementos, atributos o valores. Si Expression1 se resuelve en una secuencia vacía, no se produce ninguna inserción ni se devuelven errores.
  • into
    Los nodos identificados por Expression1 se insertan como descendientes directos (nodos secundarios) del nodo identificado por Expression2. Si el nodo de Expression2 ya tiene uno o más nodos secundarios, se debe utilizar as first o as last para especificar dónde se desea agregar el nuevo nodo. Se agregaría al principio o al final de la lista de nodos secundarios respectivamente. Las palabras clave as first y as last se omiten cuando se insertan atributos.
  • after
    Los nodos identificados por Expression1 se insertan como nodos del mismo nivel justo después del nodo identificado por Expression2. La palabra clave after no se puede utilizar para insertar atributos. Por ejemplo, no se puede utilizar para insertar un constructor de atributos o devolver un atributo desde una consulta XQuery.
  • before
    Los nodos identificados por Expression1 se insertan como nodos del mismo nivel justo antes del nodo identificado por Expression2. La palabra clave before no se puede utilizar cuando se insertan atributos. Por ejemplo, no se puede utilizar para insertar un constructor de atributos o devolver un atributo desde una consulta XQuery.
  • Expression2
    Identifica un nodo. Los nodos identificados en Expression1 se insertan con respecto al nodo identificado por Expression2. Puede ser una expresión XQuery que devuelva una referencia a un nodo que exista en el documento al que se hace referencia actualmente. Si se devuelve más de un nodo, se produce un error en la operación de inserción. Si Expression2 devuelve una secuencia vacía, no se produce ninguna inserción ni se devuelven errores. Si Expression2 no es un singleton de manera estática, se devuelve un error estático. Expression2 no puede ser una instrucción de procesamiento, un comentario ni un atributo. Tenga en cuenta que Expression2 debe ser una referencia a un nodo existente en el documento y no a un nodo construido.

Ejemplos

A. Insertar nodos de elemento en el documento

En el siguiente ejemplo se muestra cómo insertar elementos en un documento. Primero, se asigna un documento XML a una variable de tipo xml. Después, por medio de varias instrucciones insert XML DML, se muestra cómo se insertan nodos de elemento en el documento. Después de cada inserción, la instrucción SELECT muestra el resultado.

USE AdventureWorks;
GO
DECLARE @myDoc xml       
SET @myDoc = '<Root>       
    <ProductDescription ProductID="1" ProductName="Road Bike">       
        <Features>       
        </Features>       
    </ProductDescription>       
</Root>'       
SELECT @myDoc       
-- insert first feature child (no need to specify as first or as last)       
SET @myDoc.modify('       
insert <Maintenance>3 year parts and labor extended maintenance is available</Maintenance> 
into (/Root/ProductDescription/Features)[1]') 
SELECT @myDoc       
-- insert second feature. We want this to be the first in sequence so use 'as first'       
set @myDoc.modify('       
insert <Warranty>1 year parts and labor</Warranty>        
as first       
into (/Root/ProductDescription/Features)[1]       
')       
SELECT @myDoc       
-- insert third feature child. This one is the last child of <Features> so use 'as last'       
SELECT @myDoc       
SET @myDoc.modify('       
insert <Material>Aluminium</Material>        
as last       
into (/Root/ProductDescription/Features)[1]       
')       
SELECT @myDoc       
-- Add fourth feature - this time as a sibling (and not a child)       
-- 'after' keyword is used (instead of as first or as last child)       
SELECT @myDoc       
set @myDoc.modify('       
insert <BikeFrame>Strong long lasting</BikeFrame> 
after (/Root/ProductDescription/Features/Material)[1]       
')       
SELECT @myDoc;
GO

Tenga en cuenta que diversas expresiones de ruta de acceso de este ejemplo especifican "[1]" como requisito para los tipos estáticos. De esta manera se garantiza que hay un único nodo de destino.

B. Insertar varios elementos en el documento

En el ejemplo siguiente, primero se asigna un documento a una variable de tipo xml. Después, se insertan dos elementos, características de producto.

USE AdventureWorks;
GO
DECLARE @myDoc xml           
SET @myDoc = '<Root>           
<ProductDescription ProductID="1" ProductName="Road Bike">           
    <Features> </Features>           
</ProductDescription>           
</Root>'           
SELECT @myDoc           
-- insert first feature children (no need to specify as first or last)           
SET @myDoc.modify('           
insert (           
    <Warranty>1 year parts and labor</Warranty>,           
    <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>           
   )           
into (/Root/ProductDescription/Features)[1] ')           
SELECT @myDoc;
GO

Observe que los nodos de elemento de la secuencia están separados por una coma y se incluyen entre paréntesis. Así es como se construye una secuencia en XQuery.

C. Insertar atributos en un documento

En el ejemplo siguiente se muestra cómo se insertan atributos en un documento. En primer lugar, se asigna un documento a una variable de tipo xml. Después, se utiliza una serie de instrucciones insert XML DML para insertar atributos en el documento. Después de cada inserción de atributo, la instrucción SELECT muestra el resultado.

USE AdventureWorks;
GO
DECLARE @myDoc xml           
SET @myDoc = 
'<Root>           
    <Location LocationID="10" >           
        <step>Manufacturing step 1 at this work center</step>           
        <step>Manufacturing step 2 at this work center</step>           
    </Location>           
</Root>' 
SELECT @myDoc           
-- insert LaborHours attribute           
SET @myDoc.modify('           
insert attribute LaborHours {".5" }           
into (/Root/Location[@LocationID=10])[1] ')           
SELECT @myDoc           
-- insert MachineHours attribute but its value is retrived from a sql variable @Hrs           
DECLARE @Hrs float           
SET @Hrs =.2           
SET @myDoc.modify('           
insert attribute MachineHours {sql:variable("@Hrs") }           
into   (/Root/Location[@LocationID=10])[1] ')           
SELECT @myDoc           
-- insert sequence of attribute nodes (note the use of ',' and ()            
-- around the attributes.           
SET @myDoc.modify('           
insert (            
           attribute SetupHours {".5" },           
           attribute SomeOtherAtt {".2"}           
        )           
into (/Root/Location[@LocationID=10])[1] ')           
SELECT @myDoc;
GO

D. Insertar un nodo de comentario

En esta consulta primero se asigna un documento XML a una variable de tipo xml. Después, se utiliza XML DML para insertar un nodo de comentario detrás del primer elemento <step>.

USE AdventureWorks;
GO
DECLARE @myDoc xml           
SET @myDoc = 
'<Root>           
    <Location LocationID="10" >           
        <step>Manufacturing step 1 at this work center</step>           
        <step>Manufacturing step 2 at this work center</step>           
    </Location>           
</Root>'           
SELECT @myDoc           
SET @myDoc.modify('           
insert <!-- some comment -->           
after (/Root/Location[@LocationID=10]/step[1])[1] ')           
SELECT @myDoc;
GO

E. Insertar una instrucción de procesamiento

En la consulta siguiente primero se asigna un documento XML a una variable de tipo xml. Después, se utiliza la palabra clave XML DML para insertar una instrucción de procesamiento al principio del documento.

USE AdventureWorks;
GO
DECLARE @myDoc xml           
SET @myDoc = 
'<Root>           
    <Location LocationID="10" >           
        <step>Manufacturing step 1 at this work center</step>           
        <step>Manufacturing step 2 at this work center</step>           
    </Location>           
</Root>'           
SELECT @myDoc           
SET @myDoc.modify('           
insert <?Program="Instructions.exe" ?>           
before (/Root)[1] ')           
SELECT @myDoc ;
GO

F. Insertar datos mediante una sección CDATA

Cuando se inserta texto que incluye caracteres que no son válidos en XML, como < o >, se pueden utilizar secciones CDATA para insertar los datos, como se muestra en la consulta siguiente. La consulta especifica una sección CDATA, pero se agrega como un nodo de texto con los caracteres no válidos convertidos en entidades. Por ejemplo, '<' se guarda como &lt;.

USE AdventureWorks;
GO
DECLARE @myDoc xml           
SET @myDoc = 
'<Root>           
    <ProductDescription ProductID="1" ProductName="Road Bike">           
        <Features> </Features>           
    </ProductDescription>           
</Root>'           
SELECT @myDoc           
SET @myDoc.modify('           
insert <![CDATA[ <notxml> as text </notxml> or cdata ]]> 
into  (/Root/ProductDescription/Features)[1] ')  
SELECT @myDoc ;
GO

La consulta inserta un nodo de texto en el elemento <Features>:

<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features> &lt;notxml&gt; as text &lt;/notxml&gt; or cdata </Features>
</ProductDescription>
</Root>     

G. Insertar un nodo de texto

En esta consulta primero se asigna un documento XML a una variable de tipo xml. Después, se utiliza XML DML para insertar un nodo de texto como el primer elemento secundario del elemento <Root>. Para especificar el texto se utiliza el constructor de texto.

USE AdventureWorks;
GO
DECLARE @myDoc xml
SET @myDoc = '<Root>
<ProductDescription ProductID="1" ProductName="Road Bike">
<Features>

</Features>
</ProductDescription>
</Root>'
SELECT @myDoc
set @myDoc.modify('
 insert text{"Product Catalog Description"} 
 as first into (/Root)[1]
')
SELECT @myDoc

H. Insertar un nuevo elemento en una columna xml sin tipo

En el ejemplo siguiente se utiliza XML DML para actualizar una instancia XML almacenada en una columna de tipo xml:

USE AdventureWorks;
GO
CREATE TABLE T (i int, x xml);
go
INSERT INTO T VALUES(1,'<Root>
    <ProductDescription ProductID="1" ProductName="Road Bike">
        <Features>
            <Warranty>1 year parts and labor</Warranty>
            <Maintenance>3 year parts and labor extended maintenance is available</Maintenance>
        </Features>
    </ProductDescription>
</Root>')
go
-- insert a new element
UPDATE T
SET x.modify('insert <Material>Aluminium</Material> as first
  into   (/Root/ProductDescription/Features)[1]
');
GO

De nuevo, cuando se inserta el nodo de elemento <Material>, la expresión de ruta de acceso debe devolver un único destino. Esto se especifica explícitamente al agregar [1] al final de la expresión.

-- check the update
SELECT x.query(' //ProductDescription/Features')
FROM T;
GO

I. Inserción basada en una instrucción de condición IF

En el ejemplo siguiente, se especifica una condición IF como parte de Expression1 en la instrucción insert XML DML. Si la condición es True, se agrega un atributo al elemento <WorkCenter>.

USE AdventureWorks;
GO
DECLARE @myDoc xml
SET @myDoc = 
'<Root>
    <Location LocationID="10" LaborHours="1.2" >
        <step>Manufacturing step 1 at this work center</step>
    <step>Manufacturing step 2 at this work center</step>
    </Location>
</Root>'
SELECT @myDoc
SET @myDoc.modify('
insert
if (/Root/Location[@LocationID=10])
then attribute MachineHours {".5"}
else ()
    as first into   (/Root/Location[@LocationID=10])[1] ')
SELECT @myDoc;
GO

El ejemplo siguiente es similar, con la diferencia de que la instrucción insert XML DML inserta un elemento en el documento si la condición es True. En otras palabras, si el elemento <WorkCenter> tiene dos elementos secundarios <step> o menos.

USE AdventureWorks;
GO
DECLARE @myDoc xml
SET @myDoc = 
'<Root>
    <Location LocationID="10" LaborHours="1.2" >
        <step>Manufacturing step 1 at this work center</step>
        <step>Manufacturing step 2 at this work center</step>
    </Location>
</Root>'
SELECT @myDoc
SET @myDoc.modify('
insert
if (count(/Root/Location/step) <= 2)
then element step { "This is a new step" }
else ()
    as last into   (/Root/Location[@LocationID=10])[1] ')
SELECT @myDoc;
GO

El resultado es el siguiente:

<Root>
 <WorkCenter WorkCenterID="10" LaborHours="1.2">
  <step>Manufacturing step 1 at this work center</step>
  <step>Manufacturing step 2 at this work center</step>
  <step>This is a new step</step>
 </WorkCenter>

J. Insertar nodos en una columna xml con tipo

En este ejemplo se insertan un elemento y un atributo en un XML con instrucciones de fabricación almacenado en una columna xml con tipo.

En el ejemplo, primero se crea una tabla (T) con una columna xml con tipo, en la base de datos AdventureWorks. A continuación, se copia una instancia XML con instrucciones de fabricación de la columna Instructions de la tabla ProductModel a la tabla T. Después, se realizan inserciones en el XML de la tabla T.

USE AdventureWorks;
GO          
DROP TABLE T;
GO           
CREATE TABLE T(ProductModelID int primary key,  
Instructions xml (Production.ManuInstructionsSchemaCollection));
GO
INSERT T            
    SELECT ProductModelID, Instructions           
    FROM Production.ProductModel           
    WHERE ProductModelID=7;
GO           
SELECT Instructions           
FROM T;
-- now insertion begins           
--1) insert a new manu. Location. The <Root> specified as            
-- expression 2 in the insert() must be singleton.    
UPDATE T 
set Instructions.modify(' 
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions"; 
insert <MI:Location LocationID="1000" > 
           <MI:step>New instructions go here</MI:step> 
         </MI:Location> 
as first 
into   (/MI:root)[1] 
') 
         
SELECT Instructions           
FROM T ;
-- 2) insert attributes in the new <Location>           
UPDATE T           
SET Instructions.modify('           
declare namespace MI="https://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ProductModelManuInstructions";           
insert attribute LaborHours { "1000" }           
into (/MI:root/MI:Location[@LocationID=1000])[1] '); 
GO           
SELECT Instructions           
FROM T ;
GO           
--cleanup           
DROP TABLE T ;
GO           

Vea también

Conceptos

XML con tipo y sin tipo
Tipo de datos xml
Generar instancias XML
Lenguaje de manipulación de datos XML (XML DML)
Aplicaciones XML de ejemplo

Otros recursos

Métodos de tipo de datos xml

Ayuda e información

Obtener ayuda sobre SQL Server 2005