IBM PureData System for Analytics, Version 7.1

Cómo empezar: Publicar datos SQL como XML

Puede utilizar las funciones XMLElement(), XMLConcat(), XMLAgg() y XMLAttributes() dentro de una expresión SQL para transformar los resultados de una consulta de bases de datos en XML.

Estas funciones XML se denominan con frecuencia funciones de publicación porque el objetivo es convertir los datos almacenados en una base de datos relacional en XML que pueda ponerse a disposición de otras aplicaciones, por ejemplo, servicios web. La función principal a este respecto es XMLElement(), que adopta dos argumentos, el nombre del elemento XML para crear y el contenido de ese elemento. La siguiente sentencia de selección (que no consulta en realidad a una base de datos) resalta el uso de XMLElement():
select XMLElement('Parent', 'Parent Text');
Esta sentencia crea el siguiente XML:
<Parent>Parent Text</Parent>
Es importante tener en cuenta que el resultado de la función XMLElement() es un valor de tipo XML, que es la representación compilada en IBM® Netezza del elemento XML. Por lo tanto, si ha escrito la sentencia de selección anterior, el resultado sería el XML de nombre de tipo:
 XMLELEMENT
-----------
 XML
(1 row)
Para ver el elemento XML real creado por la llamada a XMLElement(), tendrá que ajustar la llamada XMLElement() con XMLSerialize(). Por ejemplo:
select XMLSerialize(XMLElement('Parent', 'Parent Text'));
         XMLSERIALIZE
------------------------------
 <Parent>Parent Text</Parent>
(1 row)
La potencia real de la función XMLElement() es que las llamadas a la función se pueden anidar para generar la estructura jerárquica que necesitan los datos XML. Por ejemplo:
 select
      XMLElement('Parent',
      XMLElement('Child', 'Child text'));
Esta consulta genera el siguiente XML:
<Parent>
   <Child>Child text</Child>
</Parent>
Las funciones de publicación se pueden anidar según sea necesario hasta un límite de 10.000 llamadas anidadas. Por ejemplo:
select
      XMLElement('Parent',
      XMLElement('Child',
      XMLElement('GrandChild', 'Grandchild text')));
Esta consulta genera el siguiente XML:
<Parent>
   <Child>
      <GrandChild>Grandchild text</GrandChild>
   </Child>
</Parent>
A modo de ejemplo más realista, supongamos que existe una tabla DEPARTMENTS con tres columnas: DEPTNO, DEPTNAME y DEPTLOC:
   DEPTNO  DEPTNAME    DEPTLOC
   ------  ----------  ---------
   10      MARKETING   BOSTON
   20      HR          BOSTON
   30      SALES       NEW YORK
   40      ENGINEERING NEW YORK
Una consulta SQL sencilla para mostrar en una lista todos los departamentos sería similar a:
select * from departments;
Pero supongamos que necesita mostrar en los resultados las cuatro filas de los datos de departamento como XML, con un nodo <Dept> para cada departamento y cada nodo <Dept> con tres nodos secundarios, <Number>, <Name> y <Location>, como se muestra en el siguiente documento XML:
<Departments>
      <Dept>
         <Number>10</Number>
         <Name>MARKETING</Name>
         <Location>BOSTON</Location>
      </Dept>
      <Dept>
         <Number>20</Number>
         <Name>HR</Name>
         <Location>BOSTON</Location>
      </Dept>
      <Dept>
         <Number>30</Number>
         <Name>SALES</Name>
         <Location>NEW YORK</Location>
      </Dept>
      <Dept>
         <Number>40</Number>
         <Name>ENGINEERING</Name>
         <Location>NEW YORK</Location>
      </Dept>
</Departments>
Para crear este documento XML, utilice una sentencia SELECT similar a esta:
SELECT
      XMLElement('Departments', XMLAGG(
         XMLElement('Dept', XMLConcat(
         XMLElement('Number', d.deptno),
         XMLElement('Name', d.deptname),
         XMLElement('Location', d.deptloc)))))
from departments d;

En cada una de las dos primeras llamadas XMLElement(), el contenido del elemento se crea mediante una llamada a la función XML anidada. para crear un documento XML estructurado de forma jerárquica de nodos principales y secundarios, anide las llamadas XMLElement() dentro de una sentencia SQL.

Por lo tanto, la primera función XMLElement() de la consulta crea el nodo <DEPARTMENTS> de nivel superior:
XMLElement('Departments', XMLAgg (

El agregado XMLAgg() se utiliza con el segundo argumento para indicar que el contenido del nodo <DEPARTMENTS> de nivel superior es un grupo de nodos agregados, lo que significa que estos nodos serán los nodos secundarios de un único nodo principal.

La segunda llamada XMLElement() establece <DEPT> como nombre del nodo secundario del nodo principal <Departments> y, después, se basa en las siguientes tres llamadas XMLElement() incrustadas para el contenido de cada nodo secundario <DEPT>.
XMLElement('Dept', XMLConcat(
      XMLElement('Number', d.deptno),
      XMLElement('Name', d.deptname),
      XMLElement('Location', d.deptloc)))))
Estas tres llamadas XMLElement() incrustadas crean tantos nodos secundarios <DEPT> como resulte necesario para ajustar las filas de datos devueltas desde la tabla Departments. Es importante comprender el uso de la función de agregado XMLAgg(). Este agregado combina los nodos secundarios bajo su nodo principal, que en el ejemplo anterior significa que existe un nodo <DEPARTMENTS> principal que contiene los cuatro nodos <DEPT>; sin la llamada XMLAgg, el XML generado contendría cuatro nodos <DEPARTMENTS>, cada uno de los cuales contendría un solo nodo <DEPT>, lo que daría como resultado un documento XML no válido, como se muestra a continuación:
<Departments>
      <Dept>
         <Number>10</Number>
         <Name>MARKETING</Name>
         <Location>BOSTON</Location>
      </Dept>
</Departments>
<Departments>
      <Dept>
         <Number>20</Number>
         <Name>HR</Name>
         <Location>BOSTON</Location>
      </Dept>
</Departments>
<Departments>
      <Dept>
         <Number>30</Number>
         <Name>SALES</Name>
         <Location>NEW YORK</Location>
      </Dept>
</Departments>
<Departments>
      <Dept>
         <Number>40</Number>
         <Name>ENGINEERING</Name>
         <Location>NEW YORK</Location>
      </Dept>
</Departments>

No es una sintaxis XML válida porque hay cuatro instancias del elemento de documento <DEPARTMENTS>. Esto demuestra lo importante que es utilizar la función IsValidXML() para asegurarse de que el XML creado con la biblioteca de funciones se puede analizar como XML. Además, si va a utilizar esquemas, también será responsable de elaborar XML con formato correcto (XML que se ajuste a la estructura especificada por el esquema).

Otro ejemplo: supongamos que desea obtener una lista de empleados por departamento, con las siguientes etiquetas:
<EmployeesByDepartment>
   <Dept DeptNo=“10“>
      <Name>ACCOUNTING</Name>
      <Location>NEW YORK</Location>
      <Employees>
         <Employee EmpNo=“7782“>
            <Name>CLARK</Name>
            <Job>MANAGER</Job>
            <Manager>7839</Manager>
            <Salary>2450</Salary>
         </Employee>
         <Employee EmpNo=“7839“>
            <Name>KING</Name>
            <Job>PRESIDENT</Job>
            <Salary>5000</Salary>
         </Employee>
         ...
      </Employees>
   </Dept>
   ...
<EmployeesByDepartment>
Para obtener empleados por departamento, se necesitan dos sentencias select; en primer lugar, cree una agrupación de empleados y después agrupe a los empleados por departamento:
CREATE temp table emp_grouping AS
SELECT deptno, XMLElement ('Employees', XMLAGG (
      XMLElement ('Employee', XMLAttributes ('EmpNo', empno),
         XMLConcat (
            xmlelement ('name', name),
            xmlelement ('job', job),
            xmlelement ('manager', mgr),
            xmlelement ('salary', sal),
            xmlelement ('comm', comm)))))
AS xml FROM emp INNER JOIN dept 
ON emp.deptno = dept.deptno
GROUP BY deptno;
SELECT XMLElement('EmployeesByDepartment', XMLAGG( 
         XMLElement('Dept', XMLAttributes('DeptNo', deptno), XMLConcat(
            XMLElement('Name', D.DNAME),
            XMLElement('Location', D.LOC),
            emp_grouping.xml)))) 
FROM dept INNER JOIN emp_grouping 
    ON dept.deptno = emp_grouping.deptno;


Feedback | Copyright IBM Corporation 2013 | Last updated: 2013-07-31