La manipolazione di una struttura ad albero del messaggio di grandi dimensioni può richiedere molta memoria. Se si progetta un flusso di messaggi che gestisce messaggi di grandi dimensioni formati da strutture che si ripetono, è possibile codificare delle istruzioni ESQL utili a ridurre il carico di memoria sul broker. Tali istruzioni supportano l'accesso al messaggio sia casuale che sequenziale, ma presuppongono che non sia necessario accedere all'intero messaggio in una sola volta.
Queste istruzioni ESQL fanno in modo che il broker esegua un'analisi limitata del messaggio e conservi solo quella parte della struttura ad albero del messaggio che riflette un singolo record nella memoria alla volta. Se l'elaborazione richiede di conservare le informazioni da un record all'altro (ad esempio, per calcolare un prezzo totale da una struttura ripetuta di elementi in un ordine), è possibile dichiarare, inizializzare e conservare le variabili ESQL o salvare i valori in un'altra sezione della struttura ad albero del messaggio, ad esempio LocalEnvironment.
Questa tecnica riduce la memoria utilizzata dal broker a quella necessaria per conservare i flussi di bit di input e di output completi, più la memoria necessaria per le strutture ad albero di un solo record e consente di risparmiare memoria quando si rileva nel messaggio anche un piccolo numero di ripetizioni. Il broker utilizza l'analisi parziale e la capacità di analizzare parti specifiche della struttura ad albero del messaggio da e verso la parte corrispondente del flusso di bit.
-- Copiare l'intestazione MQMD SET OutputRoot.MQMD = InputRoot.MQMD; -- Creare una cartella speciale nel messaggio di output per contenere la -- struttura ad albero di input -- Nota : SourceMessageTree è l'elemento root di un programma di analisi XML CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' NAME 'SourceMessageTree'; -- Copiare il messaggio di input in una cartella speciale nel messaggio di output -- Nota : questa è una copia da root a root che quindi non crea strutture ad albero SET OutputRoot.XML.Data.SourceMessageTree = InputRoot.XML; -- Creare una cartella speciale nel messaggio di output per contenere la struttura -- ad albero di output CREATE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Prepararsi ad eseguire il loop degli articoli acquistati 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; -- Creare un blocco in modo che sia facile interrompere l'elaborazione ProcessInvoice: BEGIN -- Se non esistono fatture nel messaggio di input, non vi sono operazioni da compiere IF NOT LASTMOVE(sourceCursor) THEN LEAVE ProcessInvoice; END IF; -- Eseguire il loop delle fatture nella struttura ad albero di origine InvoiceLoop : LOOP -- Controllare la fattura corrente e creare un'istruzione corrispondente 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' ); -- Trasformare l'istruzione corrente in un flusso di bit DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) AS BLOB); -- Se SELECT ha prodotto un risultato (cioè, non è stata filtrata dalla clausola -- WHERE), elaborare l'istruzione IF StatementBitStream IS NOT NULL THEN -- creare un campo per contenere il flusso di bit nella struttura ad albero dei risultati CREATE LASTCHILD OF resultCursor Type XML.BitStream NAME 'StatementBitStream' VALUE StatementBitStream; -- Aggiungere l'ammontare dell'istruzione corrente all'importo totale -- Notare che il cast è necessario a causa del comportamento dell'elemento di sintassi XML SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT); END IF; -- Eliminare l'albero dell'istruzione reale lasciando solo la versione del flusso di bit DELETE FIELD targetCursor.Statement; -- Passare alla fattura successiva, rimuovendo la fattura precedente e tutti -- gli elementi di testo che potrebbero essere distribuiti nelle fatture REPEAT MOVE sourceCursor NEXTSIBLING; DELETE PREVIOUSSIBLING OF sourceCursor; UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE) END REPEAT; -- Se non ci sono altre fatture da elaborare, interrompere il loop IF NOT LASTMOVE(sourceCursor) THEN LEAVE InvoiceLoop; END IF; END LOOP InvoiceLoop; END ProcessInvoice; -- Rimuovere l'origine temporanea e le cartelle di destinazione DELETE FIELD OutputRoot.XML.Data.SourceMessageTree; DELETE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Infine aggiungere l'importo totale 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>