La composición es el proceso de crear un conjunto de documentos XML a partir de datos relacionales de una colección XML. Puede componer documentos XML utilizando procedimientos almacenados. Para utilizar estos procedimientos almacenados, debe crear un archivo DAD, el cual especifica la correlación existente entre el documento XML y las tablas DB2. Los procedimientos almacenados utilizan el archivo DAD para componer el documento XML. Vea Planificación para utilizar colecciones XML para aprender a crear un archivo DAD.
El XML Extender proporciona dos procedimientos almacenados, dxxGenXML() y dxxRetrieveXML(), para componer documentos XML.
El procedimiento almacenado dxxGenXML() crea documentos XML utilizando datos almacenados en tablas de colección XML, que están especificadas por el elemento <Xcollection> en el archivo DAD, e inserta cada documento XML en una tabla resultante en calidad de fila. El usuario también puede abrir un cursor en la tabla resultante y obtener el conjunto resultante. La tabla resultante debe ser creada por la aplicación y contiene siempre una sola columna de tipo VARCHAR, CLOB, XMLVARCHAR o XMLCLOB. Adicionalmente, si se especifica YES para la validación en el archivo DAD, el XML Extender añade la columna DXX_VALID de tipo INTEGER e inserta el valor 1, para un documento XML válido, o el valor 0, para un documento no válido.
El procedimiento almacenado dxxGenXML() también permite al usuario especificar el número máximo de filas que se han de generar en la tabla resultante. Esto reduce el tiempo de proceso. El procedimiento almacenado devuelve el número real de filas de la tabla, junto con los códigos y mensajes de retorno producidos.
El correspondiente procedimiento almacenado para la descomposición es dxxShredXML(); también utiliza el archivo DAD como parámetro de entrada y no necesita que la colección XML esté habilitada.
Para componer una colección XML: dxxGenXML()
Intercale una llamada de procedimiento almacenado en su aplicación, mediante esta declaración:
dxxGenXML(CLOB(100K) DAD, /* entrada */ char(UDB_SIZE) resultTabName, /* entrada */ integer overrideType, /* entrada */ varchar(1024) override, /* entrada */ integer maxRows, /* entrada */ integer numRows, /* salida */ long returnCode, /* salida */ varchar(1024) returnMsg) /* salida */
Consulte dxxGenXML() para conocer la sintaxis completa y ver ejemplos.
Ejemplo: El ejemplo siguiente compone un documento XML:
#include "dxx.h" #include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; SQL TYPE is CLOB(100K) dad; /* DAD */ SQL TYPE is CLOB_FILE dadFile; /* archivo DAD */ char result_tab[32]; /* nombre de la tabla resultante */ char override[2]; /* alteración temporal, para NULL */ short overrideType; /* definido en dxx.h */ short max_row; /* número máximo de filas */ short num_row; /* número real de filas */ long returnCode; /* código de error de retorno */ char returnMsg[1024]; /* texto del mensaje de error */ short dad_ind; short rtab_ind; short ovtype_ind; short ov_inde; short maxrow_ind; short numrow_ind; short returnCode_ind; short returnMsg_ind; EXEC SQL END DECLARE SECTION; /* crear tabla */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* leer datos de un archivo y ponerlos en un CLOB */ strcpy(dadfile.name,"c:\dxx\samples\dad\getstart_xcollection.dad"); dadfile.name_length = strlen("c:\dxx\samples\dad\getstart_xcollection.dad"); dadfile.file_options = SQL_FILE_READ; EXEC SQL VALUES (:dadfile) INTO :dad; strcpy(result_tab,"xml_order_tab"); override[0] = '\0'; overrideType = NO_OVERRIDE; max_row = 500; num_row = 0; returnCode = 0; msg_txt[0] = '\0'; collection_ind = 0; dad_ind = 0; rtab_ind = 0; ov_ind = -1; ovtype_ind = 0; maxrow_ind = 0; numrow_ind = -1; returnCode_ind = -1; returnMsg_ind = -1; /* Llamar al procedimiento almacenado */ EXEC SQL CALL dxxGenXML(:dad:dad_ind; :result_tab:rtab_ind, :overrideType:ovtype_ind,:override:ov_ind, :max_row:maxrow_ind,:num_row:numrow_ind, :returnCode:returnCode_ind,:returnMsg:returnMsg_ind);
Después de llamar al procedimiento almacenado, la tabla resultante contiene 250 filas, pues la consulta SQL especificada en el archivo DAD generó 250 documentos XML.
El procedimiento almacenado dxxRetrieveXML() trabaja de la misma manera que el procedimiento almacenado dxxGenXML(), salvo que utiliza como entrada el nombre de una colección XML habilitada en lugar de un archivo DAD. Cuando se habilita una colección XML, se almacena un archivo DAD en la tabla XML_USAGE. Por tanto, el XML Extender recupera el archivo DAD y, a partir de este punto, dxxRetrieveXML() se comporta igual que dxxGenXML().
dxxRetrieveXML() permite que un mismo archivo DAD sea utilizado tanto para la composición como para la descomposición. Este procedimiento almacenado también se puede utilizar para recuperar documentos XML descompuestos.
El correspondiente procedimiento almacenado para la descomposición es dxxInsertXML(); también utiliza como entrada el nombre de una colección XML habilitada.
Para componer una colección XML: dxxRetrieveXML()
Intercale una llamada de procedimiento almacenado en su aplicación, mediante esta declaración:
dxxRetrieveXML(char(UDB_SIZE) collectionName, /* entrada */ char(UDB_SIZE) resultTabName, /* entrada */ integer overrideType, /* entrada */ varchar(1024) override, /* entrada */ integer maxRows, /* entrada */ integer numRows, /* salida */ long returnCode, /* salida */ varchar(1024) returnMsg) /* salida */
Consulte dxxRetrieveXML() para conocer la sintaxis completa y ver ejemplos.
Ejemplo: El ejemplo siguiente es una llamada a dxxRetrieveXML(). En el ejemplo, se crea la tabla resultante XML_ORDER_TAB, la cual tiene una sola columna de tipo XMLVARCHAR.
#include "dxx.h" #include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* almacenamiento intermedio con DAD */ char result_tab[32]; /* nombre de la tabla resultante */ char override[2]; /* alteración temporal, para NULL */ short overrideType; /* definido en dxx.h */ short max_row; /* número máximo de filas */ short num_row; /* número real de filas */ long returnCode; /* código de error de retorno */ char returnMsg[1024]; /* texto del mensaje de error */ short dadbuf_ind; short rtab_ind; short ovtype_ind; short ov_inde; short maxrow_ind; short numrow_ind; short returnCode_ind; short returnMsg_ind; EXEC SQL END DECLARE SECTION; /* crear tabla */ EXEC SQL CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* inicializar variable de lenguaje principal e indicadores */ strcpy(collection,"sales_ord"); strcpy(result_tab,"xml_order_tab"); override[0] = '\0'; overrideType = NO_OVERRIDE; max_row = 500; num_row = 0; returnCode = 0; msg_txt[0] = '\0'; collection_ind = 0; rtab_ind = 0; ov_ind = -1; ovtype_ind = 0; maxrow_ind = 0; numrow_ind = -1; returnCode_ind = -1; returnMsg_ind = -1; /* Llamar al procedimiento almacenado */ EXEC SQL CALL dxxRetrieve(:collection:collection_ind; :result_tab:rtab_ind, :overrideType:ovtype_ind,:override:ov_ind, :max_row:maxrow_ind,:num_row:numrow_ind, :returnCode:returnCode_ind,:returnMsg:returnMsg_ind);
En las consultas dinámicas, puede utilizar dos parámetros opcionales para anular condiciones definidas en el archivo DAD: alteración_temporal y tipo_de_alteración_temporal. Basándose en el valor de tipo_alter_temp, la aplicación puede anular la sentencia SQL_stmt, para la correlación SQL, o las condiciones del nodo_RDB, para la correlación de nodo_RDB, en el archivo DAD.
Estos parámetros tienen los valores y reglas siguientes:
.-AND-------------------------------------------. V | >>----vía de ubicación simple--+- =----+---valor---+----------->< +- >----+ +- <----+ +- <>---+ +- >=---+ +- <=---+ '- LIKE-'
Donde:
Pueden haber espacios opcionales alrededor de las operaciones; los espacios son obligatorios alrededor del operador LIKE.
Cuando se especifica el valor XML_OVERRIDE, la expresión especificada invalida la condición del nodo_RDB, en el nodo_de_texto o nodo_de_atributo correspondiente a la vía de ubicación simple.
XML_OVERRIDE no se ajusta completamente a XPath. La vía de ubicación simple sólo se utiliza para identificar el elemento o atributo que está correlacionado con una columna.
Ejemplos:
Los ejemplos siguientes muestran una alteración dinámica de valores mediante el uso de SQL_OVERRIDE y XML_OVERRIDE. En el presente manual, la mayoría de los ejemplos de procedimientos almacenados utilizan NO_OVERRIDE.
Ejemplo: Procedimiento almacenado que hace uso de SQL_OVERRIDE.
include "dxx.h" include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* almacenamiento intermedio con DAD */ char result_tab[32]; /* nombre de la tabla resultante */ char override[256]; /* alter. temporal, SQL_stmt */ short overrideType; /* definido en dxx.h */ short max_row; /* número máximo de filas */ short num_row; /* número real de filas */ long returnCode; /* código de error de retorno */ char returnMsg[1024]; /* texto del mensaje de error */ short rtab_ind; short ovtype_ind; short ov_inde; short maxrow_ind; short numrow_ind; short returnCode_ind; short returnMsg_ind; EXEC SQL END DECLARE SECTION; /* crear tabla */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* inicializar variable de lenguaje principal e indicadores */ strcpy(collection,"sales_ord"); strcpy(result_tab,"xml_order_tab"); sprintf(override,"%s %s %s %s %s %s %s", "SELECT o.order_key, customer, p.part_key, quantity, price,", "tax, ship_id, date, mode ", "FROM order_tab o, part_tab p,", "table(select substr(char(timestamp(generate_unique())),16", "as ship_id,date,mode from ship_tab)as s", "WHERE p.price > 50.00 and s.date >'1998-12-01' AND", "p.order_key = o.order_key and s.part_key = p.part_key"); overrideType = SQL_OVERRIDE; max_row = 500; num_row = 0; returnCode = 0; msg_txt[0] = '\0'; collection_ind = 0; rtab_ind = 0; ov_ind = 0; ovtype_ind = 0; maxrow_ind = 0; numrow_ind = -1; returnCode_ind = -1; returnMsg_ind = -1; /* Llamar al procedimiento almacenado */ EXEC SQL CALL dxxRetrieve(:collection:collection_ind; :result_tab:rtab_ind, :overrideType:ovtype_ind,:override:ov_ind, :max_row:maxrow_ind,:num_row:numrow_ind, :returnCode:returnCode_ind,:returnMsg:returnMsg_ind);
En este ejemplo, el elemento <xcollection> del archivo DAD debe tener un elemento <SQL_stmt>. El parámetro alteración_temporal invalida el valor de <SQL_stmt>, pues cambia el precio para que sea mayor que 50.00 y cambia a la fecha para que sea posterior a 1998-12-01.
Ejemplo: Procedimiento almacenado que hace uso de XML_OVERRIDE.
include "dxx.h" include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* almacenamiento intermedio con DAD */ char result_tab[32]; /* nombre de la tabla resultante */ char override[256]; /* alter. temporal, SQL_stmt */ short overrideType; /* definido en dxx.h */ short max_row; /* número máximo de filas */ short num_row; /* número real de filas */ long returnCode; /* código de error de retorno */ char returnMsg[1024]; /* texto del mensaje de error */ short dadbuf_ind; short rtab_ind; short ovtype_ind; short ov_inde; short maxrow_ind; short numrow_ind; short returnCode_ind; short returnMsg_ind; EXEC SQL END DECLARE SECTION; /* crear tabla */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* inicializar variable de lenguaje principal e indicadores */ strcpy(collection,"sales_ord"); strcpy(result_tab,"xml_order_tab"); sprintf(override,"%s %s", "/Order/Part/Price > 50.00 AND ", "Order/Part/Shipment/ShipDate > '1998-12-01'"); overrideType = XML_OVERRIDE; max_row = 500; num_row = 0; returnCode = 0; msg_txt[0] = '\0'; collection_ind = 0; rtab_ind = 0; ov_ind = 0; ovtype_ind = 0; maxrow_ind = 0; numrow_ind = -1; returnCode_ind = -1; returnMsg_ind = -1; /* Llamar al procedimiento almacenado */ EXEC SQL CALL dxxRetrieve(:collection:collection_ind; :result_tab:rtab_ind, :overrideType:ovtype_ind,:override:ov_ind, :max_row:maxrow_ind,:num_row:numrow_ind, :returnCode:returnCode_ind,:returnMsg:returnMsg_ind);
En este ejemplo, el elemento <xcollection> del archivo DAD tiene un nodo_RDB para el nodo_de_elemento raíz. El valor de alteración_temporal está basado en el contenido de XML. El XML Extender convierte la vía de ubicación simple en la columna DB2 correlacionada.