Portanto, a manipulação de uma grande árvore de mensagens pode demandar uma grande quantidade de armazenamento. Se você projetar um fluxo de mensagens que manipule mensagens grandes compostas de estruturas de repetição, poderá codificar instruções ESQL específicas que ajudam a reduzir o carregamento do 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.
Esta técnica reduz a memória utilizada pelo intermediário para a quantidade necessária para conter os fluxos de bits de entrada e de saída completos, além da requerida para árvores de um registro. Fornece economia de memória mesmo quando um pequeno número de repetições é encontrado na mensagem. O intermediário utiliza uma análise parcial e a capacidade de analisar partes especificadas da árvore de mensagens para e a partir da parte correspondente do fluxo de bits.
Você pode variar estas técnicas para adequar o processamento necessário para suas mensagens. O ESQL a seguir fornece um exemplo de uma implementação e é uma regravação do exemplo ESQL em Tratando de Grandes Mensagens XML que utiliza uma única instrução SET com funções SELECT aninhadas para transformar uma mensagem contendo estruturas aninhadas e de repetição.
O ESQL depende de um conjunto de mensagens chamado LargeMessageExanple que foi criado para definir mensagens para o formato de entrada Fatura e o formato de saída Instrução. Uma mensagem chamada AllInvoices foi criada e contém um elemento global chamado Fatura, que pode repetir uma ou mais vezes e uma mensagem chamada Dados, que contém um elemento global chamado Instrução, que pode ser repetido uma ou mais vezes.
As definições dos elementos e atributos receberam os tipos de dados corretos, portanto, as instruções CAST utilizadas pelo ESQL no exemplo XML não são mais requeridas. Um formato físico XML chamado XML1 foi criado no conjunto de mensagens que permite que uma mensagem XML correspondente a estas mensagens seja analisada pelo MRM.
Quando a árvore Instrução for serializada utilizando a função ASBITSTREAM, o Conjunto de Mensagens, Tipo de Mensagem e Formato da Mensagem serão especificados como parâmetros. O parâmetro Tipo de Mensagem contém o caminho da mensagem para o elemento que está sendo serializado que, neste caso, é Dados/Instrução, porque o elemento Instrução é um filho direto da mensagem Dados.
<AllInvoices> .... </AllInvoices>
A mensagem de saída é igual à de Tratando de Grandes Mensagens XML.
CREATE COMPUTE MODULE LargeMessageExampleFlow_Compute CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN CALL CopyMessageHeaders(); -- Criar uma pasta especial na mensagem de saída para receber a árvore de entrada -- Nota : SourceMessageTree é o elemento raiz de um analisador MRM CREATE LASTCHILD OF OutputRoot.MRM DOMAIN 'MRM' NAME 'SourceMessageTree'; -- Copiar a mensagem de entrada em uma pasta especial na mensagem de saída -- Nota: Esta é uma raiz para cópia de raiz que, portanto, não construirá árvores SET OutputRoot.MRM.SourceMessageTree = InputRoot.MRM; -- Criar uma pasta especial na mensagem de saída para receber a árvore de saída CREATE FIELD OutputRoot.MRM.TargetMessageTree; -- Preparar-se para examinar os itens adquiridos DECLARE sourceCursor REFERENCE TO OutputRoot.MRM.SourceMessageTree.Invoice; DECLARE targetCursor REFERENCE TO OutputRoot.MRM.TargetMessageTree; DECLARE resultCursor REFERENCE TO OutputRoot.MRM; 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 'Monthly' AS Type, 'Full' AS Style, I.Customer.FirstName AS Customer.Name, I.Customer.LastName AS Customer.Surname, I.Customer.Title AS Customer.Title, (SELECT FIELDVALUE(II.Title) AS Title, II.UnitPrice * 1.6 AS Cost, II.Quantity AS Qty FROM I.Purchases.Item[] AS II WHERE II.UnitPrice > 0.0 ) AS Purchases.Article[], (SELECT SUM( II.UnitPrice * II.Quantity * 1.6 ) FROM I.Purchases.Item[] AS II ) AS Amount, 'Dollars' AS Amount.Currency FROM sourceCursor AS I WHERE I.Customer.LastName <> 'White' ); -- Transformar a Instrução atual em um fluxo de bits -- O parâmetro SET é configurado para o nome do conjunto de mensagens -- que contém a definição MRM -- O parâmetro TYPE contém o caminho da mensagem -- para o elemento que está sendo serializado -- O parâmetro FORMAT contém o nome do formato físico -- definido na mensagem DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream SET 'LargeMessageExample' TYPE 'Data/Statement' FORMAT 'XML1') AS BLOB); -- Se SELECT tiver produzido um resultado (ou seja, ele 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 -- O tipo do elemento está configurado para MRM.BitStream para indicar indicate -- ao Analisador MRM que esse é um fluxo de bits CREATE LASTCHILD OF resultCursor Type MRM.BitStream NAME 'Statement' VALUE StatementBitStream; -- Incluir a Quantidade da Instrução atual ao total geral SET grandTotal = grandTotal + targetCursor.Statement.Amount; 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.MRM.SourceMessageTree; DELETE FIELD OutputRoot.MRM.TargetMessageTree; -- Enfim, incluir o total geral SET resultCursor.GrandTotal = grandTotal; -- Configure a propriedade MessageType de saída como 'Data' SET OutputRoot.Properties.MessageType = 'Data'; RETURN TRUE; END; CREATE PROCEDURE CopyMessageHeaders() BEGIN DECLARE I INTEGER 1; DECLARE J INTEGER CARDINALITY(InputRoot.*[]); WHILE I < J DO SET OutputRoot.*[I] = InputRoot.*[I]; SET I = I + 1; END WHILE; END; END MODULE;