La composizione è la creazione di una serie di documenti XML che si basa sui dati relazionali contenuti in una raccolta XML. E' possibile comporre documenti XML utilizzando procedure memorizzate. Per utilizzare queste procedure memorizzate, è necessario creare un file DAD che specifica l'associazione tra il documento XML e la struttura della tabella DB2. Le procedure memorizzate utilizzano il file DAD per comporre il documento XML. Per informazioni sulla creazione di un file DAD consultare la sezione Pianificazione per le raccolte XML.
XML Extender fornisce due procedure memorizzate, dxxGenXML() e dxxRetrieveXML(), per comporre i documenti XML.
La procedura memorizzata dxxGenXML() crea documenti XML utilizzando i dati memorizzati nelle tabelle della raccolta XML specificati dall'elemento <Xcollection> nel file DAD. Questa procedura inserisce ciascun documento XML come riga all'interno di una tabella dei risultati. E' inoltre possibile posizionare il cursore sulla tabella dei risultati ed eseguire la lettura sequenziale della serie di risultati. La tabella dei risultati viene creata dall'applicazione e presenta sempre una colonna di tipo VARCHAR, CLOB, XMLVARCHAR o XMLCLOB. Inoltre, se si specifica YES per l'elemento di convalida nel file DAD, XML Extender aggiunge la colonna DXX_VALID di tipo INTEGER e inserisce il valore 1 per un documento XML valido e 0 per un documento non valido.
La procedura memorizzata dxxGenXML() consente inoltre di specificare il numero massimo di righe che sono state generate nella tabella dei risultati. In tal modo si riduce il tempo di elaborazione. La procedura memorizzata restituisce il numero effettivo di righe contenute nella tabella con i codici di ritorno e i messaggi di errore.
La procedura memorizzata corrispondente per la scomposizione è dxxShredXML() la quale rileva anche il file DAD come parametro di input e non richiede che la raccolta XML sia abilitata.
Per comporre una raccolta XML: dxxGenXML()
Comprende il richiamo di una procedura memorizzata utilizzando la seguente procedura:
dxxGenXML(CLOB(100K) DAD, /* input */ char(UDB_SIZE) resultTabName, /* input */ integer overrideType, /* input */ varchar(1024) override, /* input */ integer maxRows, /* input */ integer numRows, /* output */ long returnCode, /* output */ varchar(1024) returnMsg) /* output */
Per la sintassi completa e gli esempi consultare la sezione dxxGenXML().
Esempio: Nel seguente esempio viene composto 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; /* dad file */ char result_tab[32]; /* name of the result table */ char override[2]; /* override, will set to NULL*/ short overrideType; /* defined in dxx.h */ short max_row; /* maximum number of rows */ short num_row; /* actual number of rows */ long returnCode; /* return error code */ char returnMsg[1024]; /* error message text */ 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; /* create table */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* read data from a file to a 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; /* Call the store procedure */ 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);
La tabella dei risultati che deriva dal richiamo della procedura memorizzata contiene 250 righe in quanto l'interrogazione SQL specificata nel file DAD ha generato 250 documenti XML.
La procedura memorizzata dxxRetrieveXML() corrisponde alla procedura memorizzata dxxGenXML(), l'unica differenza è che la prima rileva il nome di una raccolta XML abilitata anziché un file DAD. Quando si abilita una raccolta XML, un file DAD viene memorizzato nella tabella XML_USAGE, XML Extender richiama tale file e dxxRetrieveXML() prosegue come la procedura memorizzata dxxGenXML().
dxxRetrieveXML() consente l'utilizzo del file DAD sia nella composizione sia nella scomposizione. E' inoltre possibile utilizzare questa procedura memorizzata per il richiamo di documento XML scomposti.
La procedura memorizzata corrispondente per la scomposizione è dxxInsertXML() la quale rileva anche il nome di una raccolta XML abilitata.
Per comporre una raccolta XML: dxxRetrieveXML()
Comprende il richiamo di una procedura memorizzata utilizzando la seguente procedura:
dxxRetrieveXML(char(UDB_SIZE) collectionName, /* input */ char(UDB_SIZE) resultTabName, /* input */ integer overrideType, /* input */ varchar(1024) override, /* input */ integer maxRows, /* input */ integer numRows, /* output */ long returnCode, /* output */ varchar(1024) returnMsg) /* output */
Per la sintassi completa e gli esempi consultare la sezione dxxRetrieveXML().
Esempio: di seguito è riportato un esempio di un richiamo di dxxRetrieveXML(). In questo esempio il nome della tabella dei risultati creata è XML_ORDER_TAB e la tabella presenta una colonna di tipo XMLVARCHAR.
#include "dxx.h" #include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* dad buffer */ char result_tab[32]; /* name of the result table */ char override[2]; /* override, will set to NULL*/ short overrideType; /* defined in dxx.h */ short max_row; /* maximum number of rows */ short num_row; /* actual number of rows */ long returnCode; /* return error code */ char returnMsg[1024]; /* error message text */ 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; /* create table */ EXEC SQL CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* initialize host variable and indicators */ 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; /* Call the store procedure */ 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);
Nelle interrogazioni dinamiche è possibile utilizzare due parametri facoltativi per sostituire le condizioni del file DAD: override e overrideType. Sulla base del parametro di input overrideType, l'applicazione può sostituire i valori tag di <SQL_stmt> per l'associazione SQL oppure le condizioni di RDB_nodes per la relativa associazione nel file DAD.
Questi parametri presentano i seguenti valori e regole:
.-AND-----------------------------------------. V | >>----simple location path--+- =----+---valore---+------------->< +- >----+ +- <----+ +- <>---+ +- >=---+ +- <=---+ '- LIKE-'
Dove:
Gli spazi accanto alle operazioni sono facoltativi; quelli accanto all'operatore LIKE sono obbligatori.
Quando si specifica il valore XML_OVERRIDE, la condizione relativa a RDB_node in test_node o attribute_node che corrisponde al percorso di ubicazione semplice viene sostituita dall'espressione specificata.
XML_OVERRIDE non è completamente compatibile con XPath. Il percorso di ubicazione semplice viene utilizzato solo per identificare l'elemento o l'attributo associato a una colonna.
Esempi:
I seguenti esempi mostrano la sostituzione dinamica mediante SQL_OVERRIDE e XML_OVERRIDE. La maggior parte degli esempi di procedura memorizzata illustrati in questa pubblicazione utilizzano NO_OVERRIDE.
Esempio: la procedura memorizzata che utilizza SQL_OVERRIDE.
include "dxx.h" include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* dad buffer */ char result_tab[32]; /* name of the result table */ char override[256]; /* override, SQL_stmt */ short overrideType; /* defined in dxx.h */ short max_row; /* maximum number of rows */ short num_row; /* actual number of rows */ long returnCode; /* return error code */ char returnMsg[1024]; /* error message text */ 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; /* create table */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* initialize host variable and indicators */ 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; /* Call the store procedure */ 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);
In questo esempio, l'elemento <xcollection> nel file DAD deve presentare un elemento <SQL_stmt>. Il parametro override sostituisce il valore <SQL_stmt>, modificando il prezzo in un valore superiore a 50.00, la data viene modificata in un valore superiore a 1998-12-01.
Esempio: la procedura memorizzata che utilizza XML_OVERRIDE.
include "dxx.h" include "dxxrc.h" EXEC SQL INCLUDE SQLCA; EXEC SQL BEGIN DECLARE SECTION; char collection[32]; /* dad buffer */ char result_tab[32]; /* name of the result table */ char override[256]; /* override, SQL_stmt */ short overrideType; /* defined in dxx.h */ short max_row; /* maximum number of rows */ short num_row; /* actual number of rows */ long returnCode; /* return error code */ char returnMsg[1024]; /* error message text */ 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; /* create table */ EXEC CREATE TABLE xml_order_tab (xmlorder XMLVarchar); /* initialize host variable and indicators */ 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; /* Call the store procedure */ 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);
In questo esempio, l'elemento <collection> nel file DAD presenta un RDB_node per element_node root. Il valore override si basa sul contenuto XML. XML Extender converte il percorso di ubicazione semplice nella colonna DB2 associata.