Quando um fluxo de bits de entrada é analisado e uma árvore lógica criada, a representação da árvore de uma mensagem MRM geralmente é maior e, em alguns casos, muito maior do que o fluxo de bits correspondente.
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.
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>
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
ASBITSTREAM(targetCursor.Statement
OPTIONS FolderBitStream
SET 'LargeMessageExample'
TYPE 'Data/Statement'
FORMAT 'XML1');
-- 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;