Asignatura: Base de Datos Titulación: Ingeniería Informática Curso: 4º Práctica 5: Oracle XML DB Notas: Recuerde guardar los scripts, utilice para ello un editor de texto. Recuerde que si no utiliza la versión 9.2 de SQL*Plus, deberá formatear la salida para poder ver los resultados por pantalla. 1. Cree las siguientes tablas de ejemplo: DROP TABLE Empleados; DROP TABLE Departamentos; CREATE TABLE Departamentos ( codigo NUMBER(4) PRIMARY KEY, nombre VARCHAR2(20) ); CREATE TABLE Empleados ( dni NUMBER(8) PRIMARY KEY, nombre VARCHAR2(20), apellido1 VARCHAR2(20), apellido2 VARCHAR2(20), departamento NUMBER(4) REFERENCES Departamentos, telefono NUMBER(9) ); INSERT INTO Departamentos VALUES (1111,'Informática'); INSERT INTO Departamentos VALUES (2222,'Ventas'); INSERT INTO Departamentos VALUES (3333,'Recursos Humanos'); INSERT INTO Departamentos VALUES (4444,'Formación'); INSERT INTO Departamentos VALUES (5555,'Contabilidad'); INSERT INTO Departamentos VALUES (6666,'Compras'); INSERT INTO Departamentos VALUES (7777,'Calidad'); INSERT INTO Empleados VALUES (001,'Pedro', 'Romerales', 'Romero',1111,234231233); INSERT INTO Empleados VALUES (002,'Mateo', 'Peralta',NULL,2222,123456789); INSERT INTO Empleados VALUES (003,'Juan', 'Español', 'Español',1111,987654321); INSERT INTO Empleados VALUES (004,'Martín', 'Martín', 'Martín',3333,12312123); INSERT INTO Empleados VALUES (005,'Lucio', 'Trucha', 'del Río',2222,176283721); INSERT INTO Empleados VALUES (006,'Antonio', 'Peralta', 'Peralta',1111,NULL);
2. XMLCOLATTVAL crea un fragmento XML, con etiqueta COLUMN y un atributo NAME, que lo iguala al nombre de la columna. Podemos cambiar el valor del atributo mediante el alias. Vea el funcionamiento de la función con los siguientes ejemplos: SELECT XMLCOLATTVAL(nombre) SELECT XMLCOLATTVAL(dni, nombre) SELECT XMLCOLATTVAL(dni as Documento, nombre) SELECT XMLCOLATTVAL(dni as Documento, nombre) 3. XMLELEMENT recibe un nombre de etiqueta (identifier), un conjunto opcional de atributos para el elemento y una expresión que servirá para construir el elemento. Devuelve una instancia de tipo XMLType. Es habitual utilizarla anindándola para construir una estructura anidada XML. XMLELEMENT permite incluir atributos en el elemento utilizando la función XMLATTRIBUTES. Si dicha función recibe como expresión NULL, no se creará el atributo. Vea el funcionamiento de la función con los siguientes ejemplos: SELECT XMLELEMENT( Documento, dni) SELECT XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 ) SELECT XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 ), XMLELEMENT( Documento, dni) SELECT XMLELEMENT ("NombreEmpleado", XMLATTRIBUTES (dni AS Documento ), nombre ' ' apellido1 ' ' apellido2) as Resultado SELECT XMLELEMENT ( Emp, XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 ), XMLELEMENT( Documento, dni)) SELECT XMLELEMENT ( Emp,
XMLCOLATTVAL (dni, nombre, apellido1 apellido2 as APELLIDOS)) 4. SYS_XMLGen es similar a la función XMLElement(), pero en este caso, la función recibe un único argumento y devuelve un documento XML bien formado. SELECT SYS_XMLGen(XMLELEMENT ("Empleado", (XMLELEMENT("NombreEmpleado", XMLATTRIBUTES (dni), nombre ' ' apellido1 ' ' apellido2)), XMLELEMENT("Departamento", departamento), XMLELEMENT("Telefono", telefono))) 5. XMLAGG es una función de agregación. A partir de una colección de fragmentos XML, devuelve un único documento agregado. El siguiente ejemplo simplemente agrega la función XMLAGG a la última de las consultas anteriores. SELECT XMLAGG ( XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 )) Aunque aparentemente el resultado es el mismo, puede comprobarse que en realidad con XMLAGG el resultado es una única fila (por ejemplo, haciendo un count). En el siguiente ejemplo simplemente se añade una etiqueta al resultado anterior. SELECT XMLELEMENT("EMP",XMLAGG ( XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 ))) Observe el siguiente ejemplo y su resultado. En él se agrupan los empleados por departamento utilizando GROUP BY. SELECT XMLELEMENT("DEP", XMLAGG ( XMLELEMENT ("NombreEmpleado", nombre ' ' apellido1 ' ' apellido2 ))) as Resultado FROM empleados group by departamento; RESULTADO -------------------------------------------------------------------- <DEP> <NombreEmpleado>Pedro Romerales Romero</NombreEmpleado> <NombreEmpleado>Juan Español Español</NombreEmpleado> <NombreEmpleado>Antonio Peralta Peralta</NombreEmpleado> </DEP>
<DEP> <NombreEmpleado>Mateo Peralta </NombreEmpleado> <NombreEmpleado>Lucio Trucha del Río</NombreEmpleado> </DEP> <DEP> <NombreEmpleado>Martín Martín Martín</NombreEmpleado> </DEP> Modifique el ejemplo anterior de tal forma que cada departamento incluya, como atributo, el identificador del mismo 6. XMLFOREST convierte el conjunto de expresiones que recibe, concatenándolas a XML. El siguiente ejemplo tiene el mismo resultado que el primero de XMLELEMENT anterior: SELECT XMLFOREST (dni as "Documento") En general, XMLFOREST permite realizar consultas de forma más compacta, y además tiene como ventaja con respecto a XMLELEMENT que elimina los nulos. Sin embargo, no permite incluir atributos. Ejemplo: SELECT XMLELEMENT ("EMP", XMLAGG(XMLFOREST(dni, nombre))) Modifique el ejemplo anterior de tal forma que la consulta devuelva un único documento. 7. XMLCONCAT recibe un conjunto de instancias XMLType y los concatena. Compare los resultados de las dos siguientes consultas: SELECT XMLELEMENT ("Nom", nombre) COL1, XMLELEMENT("Ape", apellido1) COL2 SELECT XMLCONCAT(XMLELEMENT ("Nom", nombre), XMLELEMENT("Ape", apellido1)) COL Existe una función (XMLSEQUENCE) que realiza la operación inversa: a partir de una instancia XMLType devuelve el conjunto (en forma de Varray) de nodos de más alto nivel.
8. A continuación veremos algunas funciones para trabajar directamente con datos XML. Para ello, crearemos una tabla que los contenga. Podemos crear tablas XML o tablas que contengan columnas cuyo tipo de datos sea XMLType. En el primer caso, al igual que ocurre con las tablas de objetos, no existen nombres de columnas, y Oracle define una columna generada por el sistema denominada SYS_NC_ROWINFO$. La sintaxis es la siguiente: XMLType_Storage: XMLSchema_spec: XMLType_Storage nos permite indicarle al sistema cómo deseamos almacenar los datos XML: en tablas objeto-relacionales, o en CLOB. En el primer caso, deberemos especificar obligatoriamente un XMLSchema por medio de la cláusula XMLSchema_spec. En el segundo caso, simplemente debemos utilizar el tipo XMLType para la/s columnas que se desee. Al igual que en el caso anterior, podemos especificar tanto el almacenamiento como el XMLSchema para cada columna con la siguiente cláusula tras la definición de la tabla. Como puede observarse, la sintaxis es la misma que en caso anterior, excepto que debemos especificar la/s columna/s a las que estamos haciendo referencia. 9. Cree una tabla TablaXML con una columna ColumnaXML de tipo XMLType. Para insertar datos en la tabla, tenemos diferentes opciones. Una de ellas es hacer una inserción por filas, introduciendo los datos XML como una cadena de caracteres que transformaremos a XML mediante la función XMLType(): Insert into TablaXML values (xmltype('<nombre>juan</nombre> )); Otra opción es insertar el resultado de una consulta. 10. Inserte en la tabla el resultado de 4 de los ejemplos anteriores.
A continuación veremos algunas funciones que nos permiten realizar consultas a XML, o actualizar los datos. Todas ellas reciben como uno de sus parámetros una expresión XPath. 11. EXISTSNODE recibe una instancia XML y un string que especifique un XPath. Devuelve 1 si tras aplicarlo existe algún nodo y 0 en otro caso. EXTRACT es muy similar al anterior. La diferencia es que devuelve la expresión XML resultante. EXTRACTVALUE sólo puede aplicarse en el caso de que el XPath apunte a un nodo de texto, un atributo o un elemento. La función nos devuelve su contenido. Si el documento se basa en un XMLSchema y Oracle puede deducir el tipo, devuelve dicho tipo. En otro caso, devuelve un VARCHAR2. UPDATEXML recibe como argumento una instancia XMLType, un XPath y una expresión, y devuelve la instancia XMLType resultado de actualizar la que recibe como entrada con el valor de la expresión. Si XPath_string es un elemento XML, entonces value_expr debe ser una instancia XMLType. Si XPath_string es un atributo nodo de texto, entonces la expresión puede ser cualquier tipo de datos escalar. Los tipos de datos de donde apunta XPath_string y value_expr deben ser compatibles. 12. Realice una consulta a algunas de las instancias introducidas anteriormente. Modifique algunos de los datos. XMLTRANSFORM recibe como argumentos una instancia XMLTYPE y una hoja de estilo XSL, que a su vez es una instancia XMLTYPE. Aplica la hoja de estilo a la instancia y devuelve un XMLType. 13. En el siguiente ejemplo, creamos un par de tablas con una única columna de tipo XMLType. En una de ellas meteremos una instancia y en la otra la hoja de estilo: CREATE TABLE datosxml(colxml XMLType); CREATE TABLE xsl_tab (col1 XMLTYPE); En la primera insertamos una instancia válida (observe que podemos insertarlo como una cadena de caracteres transformándola a tipo XMLType).
insert into datosxml values (xmltype('<empleado> <nombre>juan</nombre> <apellido>garcia</apellido> </empleado> )); / En la segunda, la hoja de estilo. INSERT INTO xsl_tab VALUES ( XMLTYPE.createxml( '<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" > <xsl:output encoding="utf-8"/> <!-- alphabetizes an xml tree --> <xsl:template match="*"> <xsl:copy> <xsl:apply-templates select="* text()"> <xsl:sort select="name(.)" data-type="text" order="ascending"/> </xsl:apply-templates> </xsl:copy> </xsl:template> </xsl:stylesheet> ')); A continuación, aplicamos la hoja de estilo con XMLTRANSFORM: SELECT XMLTRANSFORM(d.colxml, x.col1) FROM datosxml d, xsl_tab x; La hoja anterior tiene como objetivo ordenar alfabéticamente los elementos.