Cursors for XQuery expressions in SQL procedures
SQL Procedures support the definition of cursors on XQuery expressions. A cursor on an XQuery expression allows you to iterate over the elements of the XQuery sequence returned by the expression.
Unlike cursors defined on SQL statements, which can be defined either statically or dynamically, cursors on XQuery expressions can only be defined dynamically. To declare a cursor dynamically, it is necessary to declare a variable of type CHAR or VARCHAR to contain the XQuery expression that will define the cursor result set. The XQuery expression must be prepared before the cursor can be opened and the result set resolved.
CREATE PROCEDURE xmlProc(IN inCust XML, OUT resXML XML)
SPECIFIC xmlProc
LANGUAGE SQL
BEGIN
DECLARE SQLSTATE CHAR(5);
DECLARE stmt_text VARCHAR (1024);
DECLARE customer XML;
DECLARE cityXml XML;
DECLARE city VARCHAR (100);
DECLARE stmt STATEMENT;
DECLARE cur1 CURSOR FOR stmt;
-- Get the city of the input customer
SET cityXml = XMLQUERY('$cust/customerinfo//city' passing inCust as "cust");
SET city = XMLCAST(cityXml as VARCHAR(100));
-- Iterate over all the customers from the city using an XQUERY cursor
-- and collect the customer name values into the output XML value
SET stmt_text = 'XQUERY for $cust
in db2-fn:xmlcolumn("CUSTOMER.INFO")
/*:customerinfo/*:addr[*:city= "' || city ||'"]
return <Customer>{$cust/../@Cid}{$cust/../*:name}</Customer>';
-- Use the name of the city for the input customer data as a prefix
SET resXML = cityXml;
PREPARE stmt FROM stmt_text;
OPEN cur1;
FETCH cur1 INTO customer;
WHILE (SQLSTATE = '00000') DO
SET resXML = XMLCONCAT(resXML, customer);
FETCH cur1 INTO customer;
END WHILE;
set resXML = XMLQUERY('<result> {$res} </result>'
passing resXML as "res");
END
This SQL procedure collects the IDs and names of customers defined in a table name CUSTOMER that are located in the same city as the customer for which XML data is provided as an input parameter.
CALL xmlProc(xmlparse(document '<customerinfo Cid="5002">
<name>Jim Noodle</name>
<addr country="Canada">
<street>25 EastCreek</street>
<city>Markham</city>
<prov-state>Ontario</prov-state>
<pcode-zip>N9C-3T6</pcode-zip>
</addr>
<phone type="work">905-566-7258</phone>
</customerinfo>' PRESERVE WHITESPACE),?)
If this SQL procedure is created and run against the
SAMPLE database, it returns XML data for two customers.As parameter markers are not supported for XML values, a workaround to this limitation is to construct a dynamic SQL statement out of concatenated statement fragments that include the value of one or more local variables.
For example:
DECLARE person_name VARCHAR(128);
SET person_name = "Joe";
SET stmt_text = 'XQUERY for $fname in db2-fn:sqlquery
("SELECT doc
FROM T1
WHERE DOCID=1")//fullname where $fname/first = ''' person_name || ''';
This example returns a result set in a variable assignment for
an XQuery statement that contains an SQL fullselect. The result set
contains the full names of persons with the first name Joe
.
Functionally, the SQL portion selects the XML documents from column doc
in
table T1
that have an ID of 1
. The
XQuery portion then selects the fullname values in the XML documents
where the value first is Joe
.