A manipulação de uma árvore de mensagens grande pode exigir uma grande quantidade de armazenamento. Se você desenvolver um fluxo de mensagens que manipule mensagens grandes compostas de estruturas de repetição, poderá codificar instruções ESQL, que ajudam a reduzir a carga de armazenamento no intermediário. Essas instruções suportam o acesso aleatório e seqüencial à mensagem, mas supõem que você não necessite de acesso à mensagem completa de uma vez.
Essas instruções ESQL fazem com que o intermediário execute a análise limitada da mensagem e mantenha somente a parte da árvore de mensagens que reflita um único registro no armazenamento por vez. Se seu processamento solicitar que você retenha informações de registro a registro (por exemplo, para calcular um preço total de uma estrutura de repetição de itens em uma seqüência), você pode declarar, inicializar e manter variáveis ESQL ou pode salvar os valores em outra parte da árvore de mensagens, por exemplo, Ambiente Local.
Essa técnica reduz a memória utilizada pelo intermediário para a memória necessária para manter os fluxos de bits de entrada e de saída completos mais a memória necessária para árvores de apenas um registro e fornece economia de memória, mesmo quando um número pequeno de repetições for encontrado na mensagem. O intermediário utiliza a análise parcial e a capacidade de analisar partes específicas da árvore de mensagens na parte correspondente do fluxo de bits.
-- Copiar o cabeçalho MQMD SET OutputRoot.MQMD = InputRoot.MQMD; -- Criar uma pasta especial na mensagem de saída para receber a árvore de entrada -- Obs.: SourceMessageTree é o elemento raiz de um analisador XML CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' NAME 'SourceMessageTree'; -- Copiar a mensagem de entrada em uma pasta especial na mensagem de saída -- Obs.: Esta é uma raiz para cópia de raiz que, portanto, não construirá árvores SET OutputRoot.XML.Data.SourceMessageTree = InputRoot.XML; -- Criar uma pasta especial na mensagem de saída para receber a árvore de saída CREATE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Preparar-se para examinar os itens 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; -- Criar um bloco para que seja fácil sair do processamento ProcessInvoice: BEGIN -- Se não houver faturas na mensagem de entrada, não há nada a fazer IF NOT LASTMOVE(sourceCursor) THEN LEAVE ProcessInvoice; END IF; -- Examinar as faturas na árvore de origem InvoiceLoop : LOOP -- Inspecionar a fatura atual e criar uma Instrução correspondente SET targetCursor.Statement = THE ( SELECT 'Mensal' AS (XML.Attribute)Type, 'Completo' 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' ); -- Transformar a Instrução atual em um fluxo de bits DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) AS BLOB); -- Se SELECT produziu um resultado (ou seja, não foi filtrado pela cláusula WHERE), -- processe a Instrução IF StatementBitStream IS NOT NULL THEN -- criar um campo para conter o fluxo de bits na árvore de resultados CREATE LASTCHILD OF resultCursor Type XML.BitStream NAME 'StatementBitStream' VALUE StatementBitStream; -- Incluir a Quantidade da Instrução atual ao total geral -- Observar que a conversão é necessária por causa do comportamento do elemento da sintaxe XML SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT); END IF; -- Excluir a árvore Instrução real deixando apenas a versão do fluxo de bits DELETE FIELD targetCursor.Statement; -- Ir para a próxima fatura, removendo a anterior e todos os -- elementos de texto que possam ter sido intercalados com as Faturas REPEAT MOVE sourceCursor NEXTSIBLING; DELETE PREVIOUSSIBLING OF sourceCursor; UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE) END REPEAT; -- Se não houver mais faturas para processar, abandonar o loop IF NOT LASTMOVE(sourceCursor) THEN LEAVE InvoiceLoop; END IF; END LOOP InvoiceLoop; END ProcessInvoice; -- Remover as pastas temporárias de origem e destino DELETE FIELD OutputRoot.XML.Data.SourceMessageTree; DELETE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Enfim, incluir o total geral SET resultCursor.GrandTotal = grandTotal;
<Dados> <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>