La manipulación de un árbol de mensaje de gran tamaño puede requerir mucho almacenamiento. Si diseña un flujo de mensajes que maneja mensajes de gran tamaño compuestos de estructuras repetitivas, puede codificar sentencias ESQL que le ayuden a disminuir la carga de almacenamiento del intermediario. Estas sentencias permiten acceder al mensaje de forma aleatoria y secuencial, pero presuponga que no necesita acceder a todo el mensaje de una vez.
Estas sentencias ESQL hacen que el intermediario efectúe un análisis limitado del mensaje y guarde solamente esa parte del árbol de mensaje que refleje un registro individual del almacenamiento cada vez. Si el proceso requiere que retenga la información de registro a registro, por ejemplo, para calcular un precio total de una estructura de elementos repetitivos dentro de un orden, puede declarar, inicializar y mantener variables ESQL o puede guardar los valores en otra parte del árbol de mensaje, por ejemplo, en LocalEnvironment.
Esta técnica reduce la memoria que utiliza el intermediario a la necesaria para guardar las corrientes de bits de entrada y salida completas más la necesaria para los árboles de un solo registro y permite ahorrar memoria cuando se encuentra en el mensaje incluso un pequeño número de repeticiones. El intermediario utiliza el análisis parcial y la posibilidad de analizar partes especificadas del árbol de mensaje a y desde la parte correspondiente de la corriente de bits.
-- Copiar la cabecera MQMD SET OutputRoot.MQMD = InputRoot.MQMD; -- Crear una carpeta especial en el mensaje de salida que contenga el árbol de entrada -- Nota : SourceMessageTree es el elemento raíz de un analizador XML CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' NAME 'SourceMessageTree'; -- Copiar el mensaje de entrada en una carpeta especial del mensaje de salida -- Nota : Esta es una copia de raíz a raíz que, por lo tanto, no creará árboles SET OutputRoot.XML.Data.SourceMessageTree = InputRoot.XML; -- Crear una carpeta especial en el mensaje de salida que contenga el árbol de salida CREATE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Preparar el bucle a través de los elementos adquiridos DECLARE sourceCursor REFERENCE TO OutputRoot.XML.Data.SourceMessageTree.Invoice; DECLARE targetCursor REFERENCE TO OutputRoot.XML.Data.TargetMessageTree; DECLARE resultCursor REFERENCE TO OutputRoot.XML.Data; DECLARE grandTotal FLOAT 0.0e0; -- Crear un bloque que facilite el abandono del proceso ProcessInvoice: BEGIN -- Si no hay facturas (Invoices) en el mensaje de entrada, no hay nada que hacer IF NOT LASTMOVE(sourceCursor) THEN LEAVE ProcessInvoice; END IF; -- Crear un bucle por las facturas del árbol de origen InvoiceLoop : LOOP -- Inspeccionar la factura actual y crear una sentencia coincidente SET targetCursor.Statement = THE ( SELECT 'Monthly' AS (XML.Attribute)Type, 'Full' AS (0x03000000)Style[1], I.Customer.FirstName AS Customer.Name, I.Customer.LastName AS Customer.Surname, I.Customer.Title AS Customer.Title, (SELECT FIELDVALUE(II.Title) AS Title, CAST(II.UnitPrice AS FLOAT) * 1.6 AS Cost, II.Quantity AS Qty FROM I.Purchases.Item[] AS II WHERE II.UnitPrice > 0.0 ) AS Purchases.Article[], (SELECT SUM( CAST(II.UnitPrice AS FLOAT) * CAST(II.Quantity AS FLOAT) * 1.6 ) FROM I.Purchases.Item[] AS II ) AS Amount, 'Dollars' AS Amount.(XML.Attribute)Currency FROM sourceCursor AS I WHERE I.Customer.LastName <> 'White' ); -- Convertir la sentencia actual en una corriente de bits DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) AS BLOB); -- Si SELECT ha generado un resultado, esto es, si la cláusula WHERE no la -- filtrado, procesar la sentencia IF StatementBitStream IS NOT NULL THEN -- crear un campo que contenga la corriente de bits del árbol de resultados CREATE LASTCHILD OF resultCursor Type XML.BitStream NAME 'StatementBitStream' VALUE StatementBitStream; -- Añadir el importe de la sentencia actual al total -- Tener en cuenta que cast es necesario debido al comportamiento del elemento de sintaxis XML SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT); END IF; -- Suprimir el árbol de sentencia real dejando solo la versión de la corriente de bits DELETE FIELD targetCursor.Statement; -- Pasar a la siguiente factura y suprimir la factura anterior y cualquier -- elemento de texto que se haya propagado con las facturas REPEAT MOVE sourceCursor NEXTSIBLING; DELETE PREVIOUSSIBLING OF sourceCursor; UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE) END REPEAT; -- Si no hay más facturas que procesar, abandonar el bucle IF NOT LASTMOVE(sourceCursor) THEN LEAVE InvoiceLoop; END IF; END LOOP InvoiceLoop; END ProcessInvoice; -- Suprimir las carpetas de origen y destino temporales DELETE FIELD OutputRoot.XML.Data.SourceMessageTree; DELETE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Finalmente añadir el total SET resultCursor.GrandTotal = grandTotal;
<Data> <Statement Type="Monthly" Style="Full"> <Customer> <Name>Andrew</Name> <Surname>Smith</Surname> <Title>Mr</Title> </Customer> <Purchases> <Article> <Title>The XML Companion </Title> <Cost>4.472E+1</Cost> <Qty>2</Qty> </Article> <Article> <Title>A Complete Guide to DB2 Universal Database</Title> <Cost>6.872E+1</Cost> <Qty>1</Qty> </Article> <Article> <Title>JAVA 2 Developers Handbook</Title> <Cost>9.5984E+1</Cost> <Qty>1</Qty> </Article> </Purchases> <Amount Currency="Dollars">2.54144E+2</Amount> </Statement> <GrandTotal>2.54144E+2</GrandTotal> </Data>