Actualizaciones parciales de documentos XML

Para actualizar parte de un documento XML en una columna de XML, utilice la sentencia SQL UPDATE con la función escalar XMLMODIFY incorporada.

Inicio del cambioLa función XMLMODIFY especifica uno de los siguientes tipos de expresiones:fin del cambio

Inicio del cambio
  • Una única expresión de actualización básica que puede utilizar para insertar un nodo, eliminar un nodo, reemplazar un nodo o reemplazar los valores de un nodo en un documento XML almacenado en columnas XML.
  • Una expresión de actualización que incluye más de una expresión de actualización básica. La expresión de actualización puede ser una de las siguientes expresiones:
    • Una expresión de secuencia
    • Una expresión FLWOR que contiene una expresión de actualización en su cláusula de retorno
    • Una expresión condicional que contiene una expresión de actualización en su cláusula THEN o ELSE
fin del cambio

Antes de poder utilizar XMLMODIFY para actualizar parte de un documento XML, la columna que contiene el documento XML debe ser compatible con las versiones XML.

Los tipos de expresiones básicas de actualización son:

Expresión de inserción
Inserta copias de uno o más nodos en una posición designada en una secuencia de nodos.
Expresión de sustitución
Sustituye un nodo existente con una secuencia nueva de cero o más nodos o sustituye el valor de un nodo conservando, a la vez, la identidad del nodo.
Expresión de supresión
Suprime cero o más nodos de una secuencia de nodos.

Ejemplo

Supongamos que desea reemplazar el segundo nodo de e shipTo encia en un documento de e purchaseOrder encia que tiene el ID de orden de compra (POID) 5000, y tiene este aspecto:

<ipo:purchaseOrder
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ipo="http://www.example.com/IPO"
   orderDate="2008-12-01">
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Helen Zoe</name>
    <street>55 Eden Street</street>
    <city>San Jose</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Joe Lee</name>
    <street>66 University Avenue</street>
    <city>Palo Alto</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <billTo xsi:type="ipo:USAddress">
    <name>Robert Smith</name>
    <street>8 Oak Avenue</street>
    <city>Old Town</city>
    <state>PA</state>
    <zip>95819</zip>
  </billTo>
  <items>
    <item partNum="833-AA">
      <productName>Lapis necklace</productName>
      <quantity>1</quantity>
      <USPrice>99.95</USPrice>
      <ipo:comment>Want this for the holidays!</ipo:comment>
      <shipDate>2008-12-05</shipDate>
    </item>
    <item partNum="945-ZG">
      <productName>Sapphire Bracelet</productName>
      <quantity>2</quantity>
      <USPrice>178.99</USPrice>
      <shipDate>2009-01-03</shipDate>
    </item>
  </items>
</ipo:purchaseOrder>

Puede utilizar una instrucción SQL UPDATE como esta para reemplazar el nodo " shipTo ":

UPDATE PURCHASEORDER
 SET INFO = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
  replace node /ipo:purchaseOrder/shipTo[name="Joe Lee"]
  with $x', XMLPARSE(
   '<shipTo exportCode="1" xsi:type="ipo:USAddress">
    <name>Joe Lee</name>
    <street>555 Quarry Road</street>
    <city>Palo Alto</city>
    <state/>CA
    <postcode>94304</postcode>
    </shipTo>') AS "x") 
 WHERE POID=5000

Después de que se ejecute el extracto, el contenido del documento en la columna PORDER es:

<ipo:purchaseOrder
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:ipo="http://www.example.com/IPO"
   orderDate="2008-12-01">
  <shipTo exportCode="1" xsi:type="ipo:UKAddress">
    <name>Helen Zoe</name>
    <street>55 Eden Street</street>
    <city>San Jose</city>
    <state>CA</state>
    <postcode>CB1 1JR</postcode>
  </shipTo>
  <shipTo exportCode="1" xsi:type="ipo:USAddress">
   <name>Joe Lee</name>
   <street>555 Quarry Road</street>
   <city>Palo Alto</city>
   <state>CA</state>
   <postcode>94304</postcode>
  </shipTo>
  <billTo xsi:type="ipo:USAddress">
    <name>Robert Smith</name>
    <street>505 First Street</street>
    <city>Old Town</city>
    <state>PA</state>
    <zip>95819</zip>
  </billTo>
  <items>
    <item partNum="833-AA">
      <productName>Lapis necklace</productName>
      <quantity>1</quantity>
      <USPrice>99.95</USPrice>
      <ipo:comment>Want this for the holidays!</ipo:comment>
      <shipDate>2008-12-05</shipDate>
    </item>
    <item partNum="945-ZG">
      <productName>Sapphire Bracelet</productName>
      <quantity>2</quantity>
      <USPrice>178.99</USPrice>
      <shipDate>2009-01-03</shipDate>
    </item>
  </items>
</ipo:purchaseOrder>
Inicio del cambio

Ejemplo

Supongamos que, en el siguiente documento, desea realizar estos cambios en una sola invocación de XMLMODIFY:

  • Cambie la cantidad a 2 para el artículo con número de pieza 872-AA
  • Eliminar el artículo con número de referencia 945- ZG
<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

Para realizar los cambios, puede invocar XMLMODIFY con dos expresiones de actualización básicas como esta:

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
 'declare namespace ipo="http://www.example.com/IPO";
  replace value of node /ipo:purchaseOrder/items/item[@partNum="872-AA"]/quantity
  with xs:integer(2),
  delete node /ipo:purchaseOrder/items/item[@partNum="945-ZG"]’);

Una vez ejecutado el extracto, el contenido del documento es:

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>2</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
</items>
</ipo:purchaseOrder>
fin del cambio
Inicio del cambio

Ejemplo

Supongamos que, en el siguiente documento, desea aumentar el precio de cada artículo en un 10 % en una sola invocación de XMLMODIFY:

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

Para realizar los cambios, puede invocar XMLMODIFY con una expresión FLWOR como esta:

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
   for $i in /ipo:purchaseOrder/items/item
    let $p := $i/USPrice
     where xs:decimal($p)>0
   return
    replace value of node $p with $p *1.1’);

Una vez ejecutado el extracto, el contenido del documento es:

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>164.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>196.89</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>
fin del cambio
Inicio del cambio

Ejemplo

Supongamos que, en el siguiente documento, desea realizar los siguientes cambios en una sola invocación de XMLMODIFY:
  • Para cualquier artículo con una cantidad de más de uno, disminuya el precio en un 10 %
  • Para cualquier artículo con una cantidad de uno, aumente el precio en un 5 %
<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>149.99</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>178.99</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>

Para realizar los cambios, puede invocar XMLMODIFY con una expresión condicional como esta:

UPDATE PURCHASEORDER
 SET PORDER = XMLMODIFY(
  'declare namespace ipo="http://www.example.com/IPO";
   for $i in /ipo:purchaseOrder/items/item
    let $p := $i/USPrice
    let $q := $i/quantity
   where xs:decimal($p)>0 and xs:integer($q)>0
   return
   (
    if (xs:integer($q) > 1) then
     replace value of node $p with $p *0.9
    else
     replace value of node $p with $p *1.05
   )’
 );

Una vez ejecutado el extracto, el contenido del documento es:

<ipo:purchaseOrder
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:ipo="http://www.example.com/IPO"
 xmlns:pyd="http://www.examplepayment.com"
 orderDate="1999-12-01" pyd:paidDate="2000-01-07">
 <shipTo exportCode="1" xsi:type="ipo:UKAddress">
  <name>Helen Zoe</name>
  <street>47 Eden Street</street>
  <city>Cambridge</city>
  <postcode>CB1 1JR</postcode>
 </shipTo>
 <items>
  <item partNum="872-AA">
   <productName>Lawnmower</productName>
   <quantity>1</quantity>
   <USPrice>157.49</USPrice>
   <shipDate>2011-05-20</shipDate>
  </item>
  <item partNum="945-ZG">
   <productName>Sapphire Bracelet</productName>
   <quantity>2</quantity>
   <USPrice>161.09</USPrice>
   <comment>Not shipped</comment>
  </item>
 </items>
</ipo:purchaseOrder>
fin del cambio