따라서 대형 메시지 트리를 조작하는 데 많은 저장영역이 필요합니다. 반복 구조로 구성된 대형 메시지를 핸들링하는 메시지 플로우를 설계하는 경우, 브로커의 저장영역 로드를 줄이는 데 도움이 되는 특정 ESQL문을 코딩할 수 있습니다. 이러한 명령문은 메시지에 대한 임의 액세스 및 순차적 액세스를 지원하지만, 한 번에 전체 메시지에 액세스하지 않아도 되는 것으로 가정합니다.
ESQL문은 브로커가 제한된 메시지 구문 분석을 수행하도록 하고 저장영역에 한 번에 하나의 레코드를 반영하는 메시지 트리의 일부만 보존합니다. 처리 시 레코드에서 레코드로의 정보를 보유해야 하는 경우(예: 일정한 순서의 반복 항목 구조에서 총 비용 계산) ESQL 변수를 선언, 초기화 및 유지보수 하거나 메시지 트리의 다른 부분(예: LocalEnvironment)에 값을 저장할 수 있습니다.
이 기술을 사용하면 브로커가 전체 입출력 비트스트림을 보유하기 위해 필요로 했던 메모리와 하나의 레코드 트리에 필요한 메모리가 감소됩니다. 메시지에서 반복 횟수가 적어도 메모리가 절약됩니다. 브로커는 부분 구문 분석을 사용하며, 비트스트림의 해당 부분으로(부터) 메시지 트리의 지정된 부분을 구문 분석할 수 있는 기능을 사용합니다.
메시지에 필요한 프로세스에 맞게 이들 기술을 달리할 수 있습니다. 아래의 ESQL은 하나의 구현 예로써, 중첩된 반복 구조가 포함된 메시지를 변환하기 위해 중첩된 SELECT 함수가 있는 단일 SET 문을 사용하는 큰 XML 메시지 핸들링의 ESQL 예를 재작성한 것입니다.
ESQL은 Invoice 입력 형식과 Statement 출력 형식 둘 다에 대해 메시지를 정의하기 위해 작성한 LargeMessageExanple이라고 하는 메시지 세트에 의존합니다. 여러 번 반복할 수 있는 Invoice 전역 요소가 있는 AllInvoices 메시지와 여러 번 반복할 수 있는 Statement 전역 요소가 있는 Data 메시지가 작성되었습니다.
요소 및 속성 정의에는 올바른 데이터 유형이 제공되었으므로, XML 예의 ESQL에 사용된 CAST 문은 더 이상 필요하지 않습니다. 이름이 XML1인 XML 물리적 형식이 메시지 세트에서 작성되었습니다. 이 메시지 세트에서는 두 메시지에 해당되는 XML 메시지가 MRM에 의해 구문 문석될 수 있습니다.
Statement 트리가 ASBITSTREAM 함수를 사용하여 직렬화된 경우 메시지 세트, 메시지 유형 및 메시지 형식은 매개변수로 지정됩니다. 메시지 유형 매개변수에는 메시지에서 직렬화되는 요소까지의 경로가 포함됩니다(이 경우 Data/Statement). Statement 요소는 Data 메시지의 인접 하위 요소이기 때문입니다.
<AllInvoices> .... </AllInvoices>
출력 메시지는 큰 XML 메시지 핸들링에 있는 것과 같습니다.
CREATE COMPUTE MODULE LargeMessageExampleFlow_Compute CREATE FUNCTION Main() RETURNS BOOLEAN BEGIN CALL CopyMessageHeaders(); -- Create a special folder in the output message to hold the input tree -- Note : SourceMessageTree is the root element of an MRM parser CREATE LASTCHILD OF OutputRoot.MRM DOMAIN 'MRM' NAME 'SourceMessageTree'; -- Copy the input message to a special folder in the output message -- Note : This is a root to root copy which will therefore not build trees SET OutputRoot.MRM.SourceMessageTree = InputRoot.MRM; -- Create a special folder in the output message to hold the output tree CREATE FIELD OutputRoot.MRM.TargetMessageTree; -- Prepare to loop through the purchased items 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; -- Create a block so that it's easy to abandon processing ProcessInvoice: BEGIN -- If there are no Invoices in the input message, there is nothing to do IF NOT LASTMOVE(sourceCursor) THEN LEAVE ProcessInvoice; END IF; -- Loop through the invoices in the source tree InvoiceLoop : LOOP -- Inspect the current invoice and create a matching Statement 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' ); -- Turn the current Statement into a bit stream -- The SET parameter is set to the name of the message set -- containing the MRM definition -- The TYPE parameter contains the path from the from the message -- to element being serialized -- The FORMAT parameter contains the name of the physical format -- name defined in the message DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream SET 'LargeMessageExample' TYPE 'Data/Statement' FORMAT 'XML1') AS BLOB); -- If the SELECT produced a result (that is, it was not filtered -- out by the WHERE clause), process the Statement IF StatementBitStream IS NOT NULL THEN -- create a field to hold the bit stream in the result tree -- The Type of the element is set to MRM.BitStream to indicate -- to the MRM Parser that this is a bitstream CREATE LASTCHILD OF resultCursor Type MRM.BitStream NAME 'Statement' VALUE StatementBitStream; -- Add the current Statement's Amount to the grand total SET grandTotal = grandTotal + targetCursor.Statement.Amount; END IF; -- Delete the real Statement tree leaving only the bit stream version DELETE FIELD targetCursor.Statement; -- Step onto the next Invoice, removing the previous invoice and any -- text elements that might have been interspersed with the Invoices REPEAT MOVE sourceCursor NEXTSIBLING; DELETE PREVIOUSSIBLING OF sourceCursor; UNTIL (FIELDNAME(sourceCursor) = 'Invoice') OR (LASTMOVE(sourceCursor) = FALSE) END REPEAT; -- If there are no more invoices to process, abandon the loop IF NOT LASTMOVE(sourceCursor) THEN LEAVE InvoiceLoop; END IF; END LOOP InvoiceLoop; END ProcessInvoice; -- Remove the temporary source and target folders DELETE FIELD OutputRoot.MRM.SourceMessageTree; DELETE FIELD OutputRoot.MRM.TargetMessageTree; -- Finally add the grand total SET resultCursor.GrandTotal = grandTotal; -- Set the output MessageType property to be '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;