Unidad Didactica 11 - 12 - Operaciones DML y DDL - Protected

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 21

Introducción

El  analizador  de  XML  permite  manipular  archivos  XML  desde  el  lenguaje  PL/SQL.  De  este  modo,  es  posible  generar 
archivos  en  dicho  formato  de  composición.  Para  poder  implementar  esta  funcionalidad,  el  lenguaje  PL/SQL  utiliza  el 
paquete xmldom con el fin de conocer y analizar la estructura del documento XML. 

El  lenguaje  PL/SQL,  actualmente  empleado  por  los  desarrolladores  de  aplicaciones  sobre  Oracle,  cuenta  así  con  la 
posibilidad  de  evolucionar  hacia  el  lenguaje  XML.  El  analizador  de  XML  para  PL/SQL  está  escrito  en  PL/SQL  y  Java. 
Soporta todas las especificaciones publicadas por el consorcio W3C para el estándar 1.0 de XML. Además de cumplir 
perfectamente el estándar, el analizador de XML para PL/SQL permite realizar un análisis simplificado del documento, 
respetando  las  directrices  del  W3C  en  lo  relativo  al  modelo  del documento  (DOM,  Document  Object  Model).  También 
cumple las recomendaciones relativas a XSLT (hojas de estilo) y Xpath. 

El  analizador  se  encuentra  en  el  directorio  $ORACLE_HOME\xdk\plsql\parser  y  se  incluye  como  estándar  desde  la 
versión 9i. 

El siguiente esquema resume de forma sencilla cómo funciona esta herramienta a la hora de analizar un documento. 
Este esquema se aplica en los siguientes ejemplos para conocer la estructura de un documento así como los datos 
contenidos en dicho documento. 

De  este  modo,  todos  los  programas  tienen  la  misma  estructura  para  poder  analizar  un  documento  XML,  que  es  la 
siguiente: 

l Creación  de  un  nuevo  objeto  de  tipo  Parser  usando  la  función  newParser  e  inicio  del  análisis  del  documento  XML  así
como de su DTD, si está disponible.

l A continuación, tiene que proporcionarse el código fuente XML o DTD, que puede ser de tipo varchar2, CLOB (Character
Large Object Binary) o un archivo.

l Dependiendo  del  tipo  de  origen,  se  aplican  los  posibles  métodos  de  análisis  parse()  o  parseDTD(),  si  los  datos  están
almacenados  en  un  archivo;  parseBuffer()  o  parseDTDBuffer,  si  los  datos  están  contenidos  en  un  elemento  de  tipo
varchar2; o parseClob() o parseDTDClob(), si los datos de origen se almacenan en un elemento de tipo CLOB.

l Para los documentos XML que se analizan mediante una de las funciones parse, parseBuffer o parseClob, el resultado
de la ejecución de estos métodos se guarda en un documento accesible mediante getDocument().

© Éditions ENI – Todos los derechos reservados - 1-


l El método getDocument() permite obtener el resultado del análisis y aplicar también los restantes métodos del modelo
DOM.

l El  método  freeDocument  permite  liberar  los  recursos  relativos  al  documento  actualmente  utilizados  por  el  analizador,
con el fin de poder analizar otro documento.

l Por último, la instrucción freeParser() permite liberar todos los recursos.

- 2- © Éditions ENI – Todos los derechos reservados


Lectura de un archivo XML
El primer paso consiste en poder leer el archivo en formato XML desde PL/SQL e interpretar correctamente los datos 
procedentes de dicho archivo. 

Para  comprender  el  funcionamiento  del  analizador,  evidentemente,  el  método  más  sencillo  consiste  en  emplear  un 
programa  simple  de  ejemplo.  No  se  ilustran  todas  las  funcionalidades  del  analizador  pero,  a  partir  de  un  ejemplo 
funcional, siempre es posible completar los elementos omitidos de forma relativamente sencilla.  

El siguiente script permite crear un procedimiento que recibe como parámetro un nombre de archivo xml y lo abre con el fin de 
interpretar  los  datos  que  contiene.  xmlDom  y  xmlParser  son  sinónimos  públicos  de  los  paquetes  DBMS_XMLDOM  y 
DBMS_XMLPARSER. 

-- Este procedimiento permite mostrar los diferentes elementos


del documento xml
create or replace procedure MostrarElementos(doc xmlDom.DOMDocument) is
Nodos xmlDom.DOMNodeList;
longitud number;
nodo xmlDom.DOMNode;
begin
-- obtener todos los elementos del documento
Nodos:=xmlDom.getElementsByTagName(doc,’*’);
longitud :=xmlDom.getLength(Nodos);

-- recorrer todos los elementos usando un bucle


for i in 0 ..longitud -1 loop
nodo:=xmlDom.item(Nodos, i);
dbms_output.put(xmlDom.getNodeName(nodo)||’ ’);
end loop;
-- analizar la siguiente línea
dbms_output.put_line(’ ’);
end;
/
show errors;

create or replace procedure mostrarAtributos(doc xmlDom.DOMDocument) is


Nodos xmlDom.DOMNodeList;
lg1 number;
lg2 number;
nodo xmlDom.DOMNode;
elemento xmlDom.DOMElement;
Atributos xmlDom.DOMNamedNodeMap;
nomAtr varchar2(100);
valorAtr varchar2(100);
begin

-- obtener todos los elementos


Nodos:=xmlDom.getElementsByTagName(doc,’*’);
lg1:=xmlDom.getLength(Nodos);

-- recorrer todos los elementos


for i in 0..lg1-1 loop
nodo:=xmldom.item(Nodos, i);
elemento:=xmldom.makeElement(nodo);

© Éditions ENI – Todos los derechos reservados - 1-


-- nombre de la etiqueta
dbms_output.put_line(xmldom.getTagName(elemento)||’:’);
-- obtener todos los atributos de este elemento
Atributos :=xmldom.getAttributes(nodo);

if (xmldom.isNull(Atributos)= FALSE) then


lg2:=xmldom.getLength(Atributos);

-- recorrer todos los atributos


for j in 0..lg2-1 loop
nodo:=xmldom.item(Atributos,j);
nomAtr := xmldom.getNodeName(nodo);
valorAtr := xmldom.getNodeValue(nodo);
dbms_output.put(’ ’||nomAtr||’=’||valorAtr);
end loop;
dbms_output.put_line(’ ’);
end if;
end loop;
end;
/
show errors;

create or replace procedure leerxml(directorio in varchar2,


archivo in varchar2) is
p xmlparser.parser;
doc xmldom.DOMDocument;
begin
-- nuevo analizador
p:=xmlparser.NewParser;

-- definición de algunas características del analizador


xmlParser.SetValidationMode(p,FALSE);
xmlParser.setBaseDir(p, directorio);

--analizar el archivo XML


xmlParser.Parse(p, archivo);

-- obtener el documento
doc:=xmlParser.GetDocument(p);

-- mostrar los diferentes elementos


dbms_output.put_line(’Los elementos del documento son: ’);
MostrarElementos(doc);

-- mostrar los atributos de cada elemento


dbms_output.put_line(’Los atributos de los elementos son:’);
MostrarAtributos(doc);

-- liberar el documento
xmlDom.freeDocument(doc);
-- liberar el analizador
xmlParser.freeParser(p);
end;
/
show errors;

- 2- © Éditions ENI – Todos los derechos reservados


El  procedimiento  leerXml  permite  leer  y  analizar  un  documento  XML.  El  documento  XML  se  especifica  como  parámetro  del 
procedimiento: 

<?xml version ="1.0" standalone="no"?>


<!DOCTYPE equipo SYSTEM "equipo.dtd">
<nombre equipo="US Postal" pais="USA">
<corredor numero="001">ARMSTRONG</corredor>
<corredor numero="002">EKIMOV</corredor>
<corredor numero="003">HERAS</corredor>
<corredor numero="004">HINCAPIE</corredor>
<corredor numero="005">JOACHIM</corredor>
<corredor numero="006">LANDIS</corredor>
<corredor numero="007">PADRNOS</corredor>
<corredor numero="008">PENA</corredor>
<corredor numero="009">RUBIERA</corredor>
</equipo>

La ejecución del procedimiento y el resultado del mismo son los siguientes: 

SQL> set serveroutput on


SQL> execute leerXml(XML DIR,’equipo.xml’,);
Los elementos del documento son:
equipo corredor corredor corredor corredor corredor corredor corredor corredor
Los atributos de los elementos son:
nombre:
equipo=US Postal pais=USA
corredor:
numero=001
corredor:
numero=002
corredor:
numero=003
corredor:
numero=004
corredor:
numero=005
corredor:
numero=006
corredor:
numero=007
corredor:
numero=008
corredor:
numero=009

Procedimiento PL/SQL terminado correctamente.

SQL>

XML_DIR es el nombre de un objeto DIRECTORY que se corresponde con el directorio en el que se almacena el archivo 

© Éditions ENI – Todos los derechos reservados - 3-


equipo.xml. 

- 4- © Éditions ENI – Todos los derechos reservados


Aplicación de una hoja de estilos a un documento XML
Una  de  las  principales  ventajas  del  lenguaje  XML  es  la  de  poder  separar  de  forma  muy  clara  los  datos  de  la 
presentación,  lo  que  también  es  posible  hacer  en  HTML.  El  siguiente  ejemplo,  que  utiliza  las  funcionalidades  del 
analizador XML para PL/SQL, permite generar un archivo de salida. xslProcessor es un sinónimo público del paquete 
DBMS_XSLPROCESSOR. 

set serveroutput on;


create or replace procedure aplicarXSL(
directorio varchar2, archivoXml varchar2,
archivoXsl varchar2, archivoResultado varchar2,
) is
-- las variables
p xmlParser.Parser;
-- el analizador
documentoXML xmlDom.DOMDocument; -- documento
nodo xmlDom.DOMNode;
---- elementos para la hoja de estilos
motor xslProcessor.Processor;
hojaEstilo xslProcessor.Stylesheet;
documentoXSL xmlDom.DOMDocument;
elementoXsl xmlDom.DOMElement;

espacioNombre varchar2(50);
-- elementos para generar el resultado
documentoF xmlDom.DOMDocumentFragment;
elementoF xmlDom.DomNode;

begin
-- creación de un nuevo analizador
p:=xmlParser.newParser;

-- definición de algunas características de funcionamiento


xmlParser.setValidationMode(p,FALSE); -- sin validación del documento
xmlParser.setPreserveWhiteSpace(p, TRUE); -- conservar los espacios
xmlParser.setBaseDir(p, directorio); -- directorio de trabajo

-- análisis del documento XML


xmlParser.parse(p, archivoXml);

-- obtención del documento


documentoXml:=xmlParser.getDocument(p);

-- análisis del documento XML


xmlParser.parse(p, archivoXsl);

-- obtener el documento
documentoXsl:=xmlParser.getDocument(p);

-- obtener los nodos de la hoja de estilos


elementoXsl:= xmlDom.getDocumentElement(documentoXsl);

-- obtener el espacio de nombres


espacioNom:=xmlDom.getNamespace(elementoXsl);

© Éditions ENI – Todos los derechos reservados - 1-


-- crear la hoja de estilos
hojaEstilo:=xslProcessor.newStylesheet(documentoXsl,directorio||’\’||
archivoXsl);

-- aplicar la hoja de estilos


motor :=xslProcessor.newProcessor;
xslProcessor.showWarnings(motor, true);

-- generación del documento final


documentoF:=xslProcessor.processXSL(motor, hojaEstilo, documentoXML);
elementoF:=xmlDom.makeNode(documentoF);
xmlDom.writeTofile(elementoF, archivoResultado);
end;
/
show errors

Este procedimiento permite aplicar una hoja de estilos (XSL) a un documento XML y el resultado se proporciona bajo 
la forma de un tercer documento. 

La llamada al procedimiento puede realizarse del siguiente modo: 

execute aplicarXsl(XML_DIR,’equipo.xml’,’equipo.xsl’,’/tmp/equipo.out’

- 2- © Éditions ENI – Todos los derechos reservados


XSU
La  API  XSU  (Utilidad  Xml  SQL)  para  PL/SQL  permite  generar  y  almacenar  documentos  XML  desde  y  en  la  base  de 
datos. Los paquetes que permiten implementar estas funcionalidades son DBMS_XMLQuery y DBMS_XMLSave. 

1. Generación de código XML con DBMS_XMLQuery

Para  poder  generar  un  documento  XML  que  contenga  los  resultados  de  una  consulta  simple  usando  el  paquete 
DBMS_XMLQuery es necesario llevar a cabo los siguientes cinco pasos: 

l Crear  un  puntero  a  un  contexto  llamando  al  método  DBMS_XMLQuery.getCtx  y  pasándole  como  parámetro  la 
consulta.

l Introducir los valores de los distintos parámetros de la consulta usando DBMS_XMLQuery.bind.

l Definir los argumentos opcionales, como el nombre de la etiqueta ROW o ROWSET, el número de filas que se van a 
extraer...

l Escribir  los  datos  XML  en  un  elemento  CLOB  (LOB  de  caracteres)  usando  la  función  DBMS_XMLQuery.getXML.  Esta 
función puede trabajar con o sin un archivo DTD o un esquema.

l Cerrar el contexto.

a. Generación de código XML a partir de una consulta

El  siguiente  ejemplo  ilustra  de  forma  muy  sencilla  cómo  generar  datos  en  formato  XML  a  partir  del  contenido  de  la  base  de
datos:

set serveroutput on
-- Dar formato XML al resultado de una consulta
declare
contextConsulta DBMS_XMLQuery.ctxType;
resultado CLOB;
begin
-- definición del contexto de la consulta
contextConsulta:=DBMS_XMLQuery.newContext(’select * from clientes’);

-- obtener el resultado
resultado:= DBMS_XMLQuery.getXML(contextConsulta);

-- mostrar el resultado
mostrarCLOB(resultado);

-- cerrar el contexto de la consulta


DBMS_XMLQuery.closeContext(contextConsulta);
end;
/

Con el fin de facilitar la presentación de los elementos en formato CLOB, se ha escrito el método mostrarCLOB: 

create or replace procedure mostrarClob(cadena in out nocopy CLOB) is


cadenaXml varchar2(32767);
linea varchar2(2000);

© Éditions ENI – Todos los derechos reservados - 1-


begin
-- copiar el documento CLOB en un VARCHAR2
cadenaXml:=dbms_lob.SUBSTR(cadena, 32767);
loop
exit when cadenaXml is null;
-- Búsqueda de los finales de línea
linea:=substr(cadenaXml,1,instr(cadenaXml,chr(10))-1);
dbms_output.put_line(’| ’||linea);
cadenaXml:=substr(cadenaXml, instr(cadenaXml,chr(10))+1);
end loop;
end;
/

La ejecución de este script proporciona el siguiente resultado: 

<?xml version = ’1.0’?>


<ROWSET>
<ROW num="1">
<NUMCLI>1</NUMCLI>
<APELLIDO>RAMOS</APELLIDO>
<NOMBRE>Guillermo</NOMBRE>
<DIRECCION>C/ ENI</DIRECCION>
<TEL>935777777</TEL>
</ROW>
<ROW num="2">
<NUMCLI>2</NUMCLI>
<APELLIDO>LACALLE</APELLIDO>
<NOMBRE>Maria</NOMBRE>
<DIRECCION>C/ Paredes</DIRECCION>
<TEL>935777777</TEL>
</ROW>
<ROW num="3">
<NUMCLI>3</NUMCLI>
<APELLIDO>MARTIN</APELLIDO>
<NOMBRE>Bruno</NOMBRE>
<DIRECCION>C/ Mayor</DIRECCION>
<TEL>935777777</TEL>
</ROW>
<ROW num="4">
<NUMCLI>4</NUMCLI>
<APELLIDO>GAMEZ</APELLIDO>
<NOMBRE>Jeronimo</NOMBRE>
<DIRECCION>C/ Madrid</DIRECCION>
<TEL>935777777</TEL>
</ROW>
</ROWSET>

Por supuesto, el resultado es bastante satisfactorio, pero aún no constituye un documento XML utilizable tal cual. 

b. Modificación de las etiquetas ROW y ROWSET

La  API  XSU  para  PL/SQL  permite  modificar  el  nombre  de  las  etiquetas  ROW  y  ROWSET.  En  nuestro  ejemplo,  la

- 2- © Éditions ENI – Todos los derechos reservados


etiqueta ROW deberá tomar el nombre de CLIENTE y la etiqueta ROWSET el de CLIENTES. Modificando ligeramente 
el  script  anterior  y  empleando  los  métodos  setRowTag  y  setRowSetTag  se  pueden  llevar  a  cabo  estas 
modificaciones. 

Ahora el script para generar código XML será como sigue: 

set serveroutput on
-- Dar formato XML al resultado de una consulta
declare
contextConsulta DBMS_XMLQuery.ctxType;
resultado CLOB;
begin
-- definición del contexto de la consulta
contextConsulta:=DBMS_XMLQuery.newContext(’select * from clientes’);

--modificación del nombre de la etiqueta ROW


DBMS_XMLQuery.setRowTag(contextConsulta,’CLIENTE’);

--modificación del nombre de la etiqueta ROWSET


DBMS_XMLQuery.setRowSetTag(contextConsulta,’CLIENTES’);

-- obtener el resultado
resultado:= DBMS_XMLQuery.getXML(contextConsulta);

-- mostrar el resultado
mostrarCLOB(resultado);

-- cerrar el contexto de la consulta


DBMS_XMLQuery.closeContext(contextConsulta);
end;
/

Y el resultado de la ejecución del script es el siguiente: 

<?xml version = ’1.0’?>


<CLIENTES>
<CLIENTE num="1">
<NUMCLI>1</NUMCLI>
<APELLIDO>RAMOS</APELLIDO>
<NOMBRE>Guillermo</NOMBRE>
<DIRECCION>C/ ENI</DIRECCION>
<TEL>935777777</TEL>
</CLIENTE>
<CLIENTE num="2">
<NUMCLI>2</NUMCLI>
<APELLIDO>LACALLE</APELLIDO>
<NOMBRE>Maria</NOMBRE>
<DIRECCION>C/ Paredes</DIRECCION>
<TEL>935777777</TEL>
</CLIENTE>
<CLIENTE num="3">
<NUMCLI>3</NUMCLI>

© Éditions ENI – Todos los derechos reservados - 3-


<APELLIDO>MARTIN</APELLIDO>
<NOMBRE>Bruno</NOMBRE>
<DIRECCION>C/ Mayor</DIRECCION>
<TEL>935777777</TEL>
</CLIENTE>
<CLIENTE num="4">
<NUMCLI>4</NUMCLI>
<APELLIDO>GAMEZ</APELLIDO>
<NOMBRE>Jeronimo</NOMBRE>
<DIRECCION>C/ Madrid</DIRECCION>
<TEL>935777777</TEL>
</CLIENTE>
</CLIENTES>

c. Limitación del número de filas

Las filas de datos extraídas a través de la consulta pueden incluirse en una página mediante los procedimientos
setMaxRows y setSkipRows. El procedimiento  setMaxRows permite establecer el número máximo de filas de
datos  que  se  convertirán  a  formato  XML,  mientras  que  el  procedimiento  setSkipRows  permite  especificar  el
número de filas de datos que deben omitirse antes de comenzar la conversión al formato XML.

Estos procedimientos pueden utilizarse, por ejemplo, para limitar el número de filas de datos presentes en cada
documento XML.

El siguiente ejemplo permite limitar a 10 el número de clientes que se incluyen en cada documento XML generado. Con el fin
de  que  no  se  genere  ninguna  excepción  después  de  tratar  todas  las  filas,  hay  que  llamar  al  método
setRaiseNoRowsException:

set serveroutput on
-- Dar formato XML al resultado de una consulta
declare
contextConsulta DBMS_XMLQuery.ctxType;
resultado CLOB;
begin
-- definición del contexto de la consulta
contextConsulta:=DBMS_XMLQuery.newContext(’select * from clientes’);

--modificación del nombre de la etiqueta ROW


DBMS_XMLQuery.setRowTag(contextConsulta,’CLIENTE’);

--modificación del nombre de la etiqueta ROWSET


DBMS_XMLQuery.setRowSetTag(contextConsulta,’CLIENTES’);

-- definición del número filas por documento XML


DBMS_XMLQuery.setMaxRows(contextConsulta,10);
DBMS_XMLQuery.setRaiseNoRowsException(contextConsulta, true);

-- extracción de los datos


begin
loop -- bucle infinito
-- obtener el resultado
resultado:= DBMS_XMLQuery.getXML(contextConsulta);

- 4- © Éditions ENI – Todos los derechos reservados


-- mostrar el resultado
mostrarCLOB(resultado);
end loop;
exception
when others then
null; --salir del bloque en caso de error
end;

-- cierre del contexto de la consulta


DBMS_XMLQuery.closeContext(contextConsulta);
end;
/

d. Hojas de estilo

La API XSU permite utilizar hojas de estilo en la generación de documentos XML.

El procedimiento setStyleSheetHeader() permite añadir la referencia a la hoja de estilos en la cabecera del
documento resultante.

El procedimiento useStyleSheet() permite aplicar la hoja de estilos directamente al documento resultante.

La segunda solución es mejor que la primera, ya que evita tener que volver a procesar el documento para aplicar
la hoja de estilos en un segundo paso.

2. Consultas parametrizadas

Después  de  crear  el  contexto,  hay  que  proporcionar  la  consulta  SQL  que  se  utilizará  para  extraer  los  datos.  Sin 
embargo, esta consulta puede contener parámetros a los que se les asignará un valor justo antes de la ejecución 
de  la  consulta.  En  efecto,  la  consulta  solo  se  ejecuta  cuando  se  solicita  la  construcción  del  documento  XML  final 
mediante el método getXMLClob. 

Durante la escritura de la consulta, las variables se consideran como variables externas y, por tanto, van precedidas 
del signo de dos puntos (:). 

El  método  setBindValue  permite  especificar  el  valor  que  tomará  un  parámetro.  Lógicamente,  es  necesario 
inicializar el conjunto de parámetros antes de solicitar la primera generación del documento XML. Sin embargo, entre 
dos  solicitudes  de  generación  de  documento,  no  es  preciso  reinicializar  todos  los  parámetros,  sino  solamente 
aquellos que hayan cambiado.  

Ejemplo 

El  siguiente  ejemplo  ilustra  la  implementación  de  consultas  parametrizadas  para  trabajar  con  la  API  XSU.  Se  generan  dos 
documentos XML, correspondiendo cada uno de ellos a un determinado cliente, pero solo se establece un contexto XSU, ya que 
los datos proceden de la misma consulta, que dispone de un parámetro de restricción.  

set serveroutput on
-- Dar formato XML al resultado de una consulta
declare
contextConsulta DBMS_XMLQuery.ctxType;
resultado CLOB;
begin

© Éditions ENI – Todos los derechos reservados - 5-


-- definición del contexto de la consulta
contextConsulta :=DBMS_XMLQuery.newContext(’select * from clientes where
numcli=:numero’);

-- especificar el valor del parámetro


DBMS_XMLQuery.setBindValue(contextConsulta,’numero’,15);

-- obtener el resultado
resultado:= DBMS_XMLQuery.getXML(contextConsulta);
-- mostrar el resultado
mostrarCLOB(resultado);

-- especificar otro valor para el parámetro


DBMS_XMLQuery.setBindValue(contextConsulta,’numero’,20);

-- obtener el resultado
resultado:= DBMS_XMLQuery.getXML(contextConsulta);
-- mostrar el resultado
mostrarCLOB(resultado);
-- cierre del contexto de la consulta
DBMS_XMLQuery.closeContext(contextConsulta);
end;
/

3. Almacenamiento de datos en formato XML con DBMS_XMLSave

La API XSU para PL/SQL también incluye el paquete DBMS_XMLSave, el cual permite almacenar, en las tablas de la 
base  de  datos,  datos  que  inicialmente  se  encuentran  en  documentos  con  formato  XML.  Gracias  a  este  segundo 
paquete,  XSU  permite  demostrar  que  XML  es  realmente  un  formato  de  intercambio  de  datos  que  puede  utilizarse 
para realizar transferencias de datos entre bases de datos. 

Se pueden emplear los datos proporcionados en formato XML para realizar operaciones de inserción, actualización y 
borrado (instrucciones INSERT, UPDATE o DELETE). 

En general, todos los scripts PL/SQL que utilizan el paquete DBMS_XMLSave respetan la siguiente estructura: 

l Creación  de  un  contexto  de  ejecución  mediante  la  función  DBMS_XMLSave.getCtx.  Esta  función  recibe  como 
parámetro el nombre de la tabla sobre la que se realizarán las operaciones de inserción (INSERT), borrado (DELETE) 
o actualización (UPDATE).

l Si  el  documento  XML  se  utiliza  como  soporte  en  la  adición  de  datos  (INSERT)  a  la  tabla,  es  posible  especificar  las 
columnas para las que se van a suministrar valores mediante la función setUpdateColNames. Por omisión, los valores 
se proporcionan para todas las columnas de la tabla.

l Si  el  documento  XML  se  emplea  como  soporte  de  una  operación  de  actualización  de  datos  (UPDATE),  hay  que 
proporcionar la o las columnas que se van a utilizar, con el fin de identificar de forma exacta los datos que hay que 
modificar. También se pueden especificar la o las columnas que se van a actualizar.

l Si el documento XML se emplea como soporte de una operación de borrado (DELETE), se pueden especificar la o las 
columnas que se utilizarán con el fin de identificar de forma precisa los datos que hay que eliminar. Por omisión, todos 
los datos del documento XML sirven para identificar los datos que se van a eliminar.

l Proporcionar  un  documento  XML  a  uno  de  los  métodos  insertXML,  updateXML  o  deleteXML  para  llevar  a  cabo  la 
operación deseada con el documento XML.

l Cerrar el contexto.

- 6- © Éditions ENI – Todos los derechos reservados


a. Adición de datos

Para emplear los datos existentes en el documento XML con el fin de añadirlos a una tabla basta con especificar el
nombre de la tabla o vista, así como el documento XML. XSU se encarga de generar las instrucciones INSERT. Por
omisión, la instrucción INSERT afecta a todas las columnas de la tabla o vista y se emplea el valor NULL cuando no
se especifica otra cosa en el documento XML.

Ejemplo

El siguiente ejemplo ilustra el uso de la función insertXML:

create or replace procedure agregar(documentoXML in CLOB, nomTabla


in varchar2) is
contextAgregar DBMS_XMLSave.ctxType;
numFilas number;
begin
-- creación del contexto de inserción
contextAgregar:=DBMS_XMLSave.newContext(nomTabla);

-- añadir filas
numFilas:=DBMS_XMLSave.insertXML(contextAgregar, documentoXML);

-- cerrar el contexto
DBMS_XMLSave.closeContext(contextAgregar);
end;
/

El documento XML usado para agregar los datos es: 

<?xml version = ’1.0’?>


<ROWSET>
<ROW num="1">
<NUMCLI>200</NUMCLI>
<NOMCLI>E. GONZALEZ</NOMCLI>
<COD_POSTAL>28000</COD_POSTAL>
<CIUDAD>MADRID</CIUDAD>
</ROW>
</ROWSET>

La llamada al procedimiento se realiza del siguiente modo: 

-- establecer el directorio
create or replace directory "xml_dir" as ’C:\xml’;

-- carga de los datos


declare

dest_clob CLOB;
archivo_in BFILE;

© Éditions ENI – Todos los derechos reservados - 7-


tamaño number;
inicio_destino integer:=1;
inicio_origen integer:=1;
juego_caracteres number:=0;
contexto_idioma number:=0;
aviso number:=0;

vid number;
begin
archivo_in:= bfilename(’xml_dir’,’datos.xml’);

-- abrir el archivo
dbms_lob.fileopen(archivo_in, dbms_lob.file_readonly);

if (dbms_lob.fileexists(archivo_in)=1) then

-- tamaño del archivo


tamaño:=dbms_lob.getlength(archivo_in);

-- leer los datos y almacenarlos en una variable


contexto_idioma:=1;
dbms_lob.createtemporary(dest_clob, true);
dbms_lob.loadclobfromfile(dest_clob,
archivo_in,
tamaño,
inicio_destino,
inicio_origen,
juego_caracteres,
contexto_idioma,
aviso);

-- cerrar el archivo
dbms_lob.fileclose(archivo_in);

-- llamar al procedimiento para agregar datos


agregar(dest_clob, ’CLIENTES’);
-- validar las modificaciones
commit;

end if;

end;
/

También se puede emplear este método de inserción para afectar solo a determinadas columnas de la tabla de 
destino.  En  este  caso,  es  preciso  llamar  al  método  setUpdateColumn  para  especificar  el  nombre  de  las 
columnas  que  van  a  contener  los  valores  que  hay  que  insertar.  Para  eliminar  cualquier  riesgo  de  definir  mal  los 
parámetros, el método clearUpdateColumnList permite eliminar toda referencia que se haya podido hacer a 
las columnas anteriormente.  

Ejemplo 

El  ejemplo  siguiente  lee  los  datos  en  formato  XML  almacenados  en  un  archivo  y  después  carga  los  datos  en  la  tabla  de 
clientes: 

- 8- © Éditions ENI – Todos los derechos reservados


declare
-- variables necesarias para leer un archivo
documentoXML CLOB;
archivo_in BFILE;
tamaño number;
inicio_destino integer:=1;
inicio_origen integer:=1;
juego_caracteres number:=0;
contexto_idioma number:=0;
aviso number:=0;

-- variables para la adición de datos


contextAgregar DBMS_XMLSave.ctxType;
numFilas number;

begin
archivo_in:= bfilename(’xml_dir’,’datos2.xml’);

-- abrir el archivo
dbms_lob.fileopen(archivo_in, dbms_lob.file_readonly);

-- tamaño del archivo


tamaño:=dbms_lob.getlength(archivo_in);

-- leer los datos y almacenarlos en una variable


contexto_idioma:=1;
dbms_lob.createtemporary(documentoXML, true);
dbms_lob.loadclobfromfile(documentoXML,
archivo_in,
tamaño,
inicio_destino,
inicio_origen,
juego_caracteres,
contexto_idioma,
aviso);

-- cerrar el archivo
dbms_lob.fileclose(archivo_in);

-- creación del contexto de inserción


contextAgregar:=DBMS_XMLSave.newContext(’CLIENTES’);
-- borrar los parámetros
DBMS_XMLSave.clearUpdateColumnList(contextAgregar);
-- columnas para las que existe un valor
DBMS_XMLSave.setUpdateColumn(contextAgregar,’NUMCLI’);
DBMS_XMLSave.setUpdateColumn(contextAgregar,’NOMCLI’);
-- realizar las inserciones
numFilas:=DBMS_XMLSave.insertXML(contextAgregar,documentoXML);
--cerrar el contexto
DBMS_XMLSave.closeContext(contextAgregar);

-- validar las modificaciones


commit;

© Éditions ENI – Todos los derechos reservados - 9-


end;
/

b. Actualización de datos

La actualización es una operación algo más delicada, ya que es necesario indicar la o las columnas que sirven para
identificar la fila, así como la o las columnas cuyos valores se van a actualizar.

Las columnas que se usan en la identificación de filas se especifican mediante el procedimiento  setKeyColumn y


aquellas que van a actualizarse mediante el procedimiento setUpdateColumn. Si no se especifican las columnas
que van a actualizarse, se actualizarán todas las columnas de la tabla.

Ejemplo

El  siguiente  ejemplo  permite  especificar  la  ciudad  y  el  código  postal  de  los  clientes  con  números  200  y  201  (los  clientes
añadidos en los ejemplos anteriores):

declare
-- variables necesarias para leer un archivo
documentoXML CLOB;
archivo_in BFILE;
tamaño number;
inicio_destino integer:=1;
inicio_origen integer:=1;
juego_caracteres number:=0;
contexto_idioma number:=0;
aviso number:=0;

-- variables para la actualización


contextAct DBMS_XMLSave.ctxType;
numFilas number;

begin
archivo_in:= bfilename(’xml_dir’,’datos3.xml’);

-- abrir el archivo
dbms_lob.fileopen(archivo_in, dbms_lob.file_readonly);

-- tamaño del archivo


tamaño:=dbms_lob.getlength(archivo_in);

-- leer los datos y almacenarlos en una variable


contexto_idioma:=1;
dbms_lob.createtemporary(documentoXML, true);
dbms_lob.loadclobfromfile(documentoXML,
archivo_in,
tamaño,
inicio_destino,
inicio_origen,
juego_caracteres,
contexto_idioma,

- 10 - © Éditions ENI – Todos los derechos reservados


aviso);
-- cerrar el archivo
dbms_lob.fileclose(archivo_in);

-- creación del contexto de actualización


contextAct:=DBMS_XMLSave.newContext(’CLIENTES’);
-- borrar los parámetros
DBMS_XMLSave.clearUpdateColumnList(contextAct);
-- Columna de identificación
DBMS_XMLSave.setKeyColumn(contextAct,’NUMCLI’);
-- Columnas de actualización
DBMS_XMLSave.setUpdateColumn(contextAct,’COD_POSTAL’);
DBMS_XMLSave.setUpdateColumn(contextAct,’CIUDAD’);
-- efectuar las actualizaciones
numFilas:=DBMS_XMLSave.updateXML(contextAct,documentoXML);
--cerrar el contexto
DBMS_XMLSave.closeContext(contextAct);
-- validar las modificaciones
commit;

end;
/

El archivo XML que sirve de base para la actualización: 

<?xml version = ’1.0’?>


<ROWSET>
<ROW>
<NUMCLI>200</NUMCLI>
<COD_POSTAL>27000</COD_POSTAL>
<CIUDAD>PONTEVEDRA</CIUDAD>
</ROW>
<ROW>
<NUMCLI>201</NUMCLI>
<COD_POSTAL>28000</COD_POSTAL
<CIUDAD>MADRID</CIUDAD>
</ROW>
</ROWSET>

c. Borrado de los datos

Por último, se puede utilizar un documento XML para llevar a cabo el borrado de una serie de datos. Las columnas
existentes  en  el  documento  XML  servirán  para  construir  la  cláusula  WHERE.  Se  puede  limitar  el  número  de
columnas utilizadas para definir la restricción de filas llamando al procedimiento setKeyColumn.

El  siguiente  ejemplo  permite  borrar  los  clientes  número  200  y  201.  Esta  información  está  almacenada  en  un  archivo  XML
denominado datos4.xml.

declare
-- variables necesarias para leer un archivo
documentoXML CLOB;

© Éditions ENI – Todos los derechos reservados - 11 -


archivo_in BFILE;
tamaño number;
inicio_destino integer:=1;
inicio_origen integer:=1;
juego_caracteres number:=0;
contexto_idioma number:=0;
aviso number:=0;

-- variables para el borrado


contextBorrar DBMS_XMLSave.ctxType;
numFilas number;

begin
archivo_in:= bfilename(’xml_dir’,’datos4.xml’);

-- abrir el archivo
dbms_lob.fileopen(archivo_in, dbms_lob.file_readonly);

-- tamaño del archivo


tamaño:=dbms_lob.getlength(archivo_in);

-- leer los datos y almacenarlos en una variable


contexto_idioma:=1;
dbms_lob.createtemporary(documentoXML, true);
dbms_lob.loadclobfromfile(documentoXML,
archivo_in,
tamaño,
inicio_destino,
inicio_origen,
juego_caracteres,
contexto_idioma,
aviso);
-- cerrar el archivo
dbms_lob.fileclose(archivo_in);

-- creación del contexto de borrado


contextBorrar:=DBMS_XMLSave.newContext(’CLIENTES’);

-- borrar los parámetros


DBMS_XMLSave.clearUpdateColumnList(contextBorrar);
-- Columna de identificación
DBMS_XMLSave.setKeyColumn(contextBorrar,’NUMCLI’);
-- realizar el borrado
numFilas:=DBMS_XMLSave.deleteXML(contextBorrar,documentoXML);
--cierre del contexto
DBMS_XMLSave.closeContext(contextBorrar);
-- validar las modificaciones
commit;

end;
/

El  uso  del  paquete  DBMS_XMLSave  es  un  tanto  tedioso  en  lo  que  se  refiere  a  la  escritura  de  procedimientos, 
especialmente  en  el  nivel  de  inicialización  del  contexto.  Dado  que  el  contexto  está  relacionado  con  una  tabla 

- 12 - © Éditions ENI – Todos los derechos reservados


determinada, es posible crear un único contexto y utilizarlo a continuación para llevar a cabo todas las operaciones 
de actualización o de borrado. Esto se realiza agrupando los procedimientos relativos a las diferentes operaciones 
en un mismo paquete y declarando como variable global del paquete el contexto de ejecución de las instrucciones 
del paquete DBMS_XMLSave. 

© Éditions ENI – Todos los derechos reservados - 13 -

También podría gustarte