Bei der Bearbeitung einer umfangreichen Nachrichtenbaumstruktur kann ein hoher Bedarf an Speicherplatz entstehen. Wenn Sie einen Nachrichtenfluss entwerfen, der umfangreiche Nachrichten verarbeitet, die aus sich wiederholenden Strukturen bestehen, können Sie ESQL-Anweisungen codieren, die zu einer Reduzierung der Speicherbelastung im Broker führen. Diese Anweisungen unterstützen sowohl den wahlfreien als auch den sequenziellen Zugriff auf die Nachricht. Es wird jedoch vorausgesetzt, dass Sie nicht gleichzeitig auf die gesamte Nachricht zugreifen müssen.
Diese ESQL-Anweisungen veranlassen den Broker zur Ausführung einer eingeschränkten Syntaxanalyse der Nachricht. Außerdem speichert der Broker immer nur den Teil der Nachrichtenbaumstruktur, der einen einzelnen Datensatz reflektiert. Wenn in Ihrer Verarbeitung Informationen von Datensatz zu Datensatz beibehalten werden müssen (um beispielsweise den Gesamtpreis auf Grundlage einer sich wiederholenden Artikelstruktur in einer Bestellung auszurechnen), können Sie ESQL-Variablen entweder deklarieren, initialisieren und verwalten oder Werte in einem anderen Teil der Nachrichtenbaumstruktur (z. B. in der lokalen Umgebung) speichern.
Bei diesem Verfahren wird der vom Broker verwendete Speicher auf den Bedarf reduziert, der für das Speichern der vollständigen Ein- und Ausgabebitströme erforderlich ist, plus dem Speicherplatz, der für die Baumstrukturen lediglich eines Datensatzes benötigt wird. Dadurch wird selbst dann Speicherplatz gespart, wenn die Nachricht eine geringe Anzahl an Wiederholungen enthält. Der Broker nutzt die teilweise Syntaxanalyse und die Möglichkeit, angegebene Bereiche der Nachrichtenbaumstruktur in und aus dem entsprechenden Bereich des Bitstroms syntaktisch zu analysieren.
-- Copy the MQMD header SET OutputRoot.MQMD = InputRoot.MQMD; -- Create a special folder in the output message to hold the input tree -- Note : SourceMessageTree is the root element of an XML parser CREATE LASTCHILD OF OutputRoot.XML.Data DOMAIN 'XML' 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.XML.Data.SourceMessageTree = InputRoot.XML; -- Create a special folder in the output message to hold the output tree CREATE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Prepare to loop through the purchased items 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; -- 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 (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' ); -- Turn the current Statement into a bit stream DECLARE StatementBitStream BLOB CAST(ASBITSTREAM(targetCursor.Statement OPTIONS FolderBitStream) 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 CREATE LASTCHILD OF resultCursor Type XML.BitStream NAME 'StatementBitStream' VALUE StatementBitStream; -- Add the current Statement's Amount to the grand total -- Note that the cast is necessary because of the behavior of the XML syntax element SET grandTotal = grandTotal + CAST(targetCursor.Statement.Amount AS FLOAT); 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.XML.Data.SourceMessageTree; DELETE FIELD OutputRoot.XML.Data.TargetMessageTree; -- Finally add the grand total 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>