큰 XML 메시지 핸들링

입력 비트스트림이 구문 분석되고 논리적 트리가 작성되면 대개 XML 메시지의 해당 비트스트림에 비해 트리 표현이 더 크며 일부의 경우에는 훨씬 더 큽니다. 그러한 이유는 다음과 같습니다.
  • 오브젝트를 같이 링크시키는 포인터 추가
  • 유니코드로의 문자 데이터 변환. 이를 통해 크기를 두 배로 늘릴 수 있습니다.
  • 비트스트림에서 내재적일 수 있는 필드 이름 포함
  • 브로커의 조작과 연관된 제어 데이터의 존재

대형 메시지 트리를 조작하는데는 많은 저장영역을 필요로 합니다. 반복 구조로 구성된 대형 메시지를 핸들링하는 메시지 플로우를 설계하는 경우, 브로커의 저장영역 로드를 줄이는 데 도움이 되는 ESQL문을 코딩할 수 있습니다. 이러한 명령문은 메시지에 대한 임의 액세스 및 순차적 액세스를 지원하지만, 한 번에 전체 메시지에 액세스하지 않아도 되는 것으로 가정합니다.

ESQL문은 브로커가 제한된 메시지 구문 분석을 수행하도록 하고 저장영역에 한 번에 하나의 레코드를 반영하는 메시지 트리의 일부만 보존합니다. 처리 시 레코드에서 레코드로의 정보를 보유해야 하는 경우(예: 일정한 순서의 반복 항목 구조에서 총 비용 계산) ESQL 변수를 선언, 초기화 및 유지보수 하거나 메시지 트리의 다른 부분(예: LocalEnvironment)에 값을 저장할 수 있습니다.

이 기술은 브로커가 전체 입출력 비트스트림을 보유하는데 필요한 메모리 및 하나의 레코드 트리에만 필요한 메모리를 감소시키며, 메시지에서의 적은 수의 반복에 대해서도 메모리가 절약됩니다. 브로커는 부분 구문 분석 및 비트스트림의 해당 부분에서(으로) 메시지 트리의 지정된 부분을 구문 분석하는 기능을 사용합니다.

Compute 노드에서 이러한 기술을 사용하려면 다음과 같은 범용 기술을 적용합니다.
  • 비트스트림으로서 입력 메시지의 본문을 출력 메시지의 특수 폴더로 복사하십시오. 이렇게 하면 구문 분석되지 않은 입력 메시지에 대한 수정 가능한 사본이 작성되고 최소량의 메모리를 사용하게 됩니다.
  • 입력 메시지를 확인하지 않도록 하십시오. 이렇게 하면 메시지를 구문 분석할 필요가 없습니다.
  • 루프 및 참조 변수를 사용하여 한 번에 한 레코드씩 메시지를 통과시키십시오. 각 레코드의 경우 다음을 수행하십시오.
    • 두 번째 특수 폴더에서 해당 출력 서브트리를 빌드하도록 정상 변환을 사용하십시오.
    • ASBITSTREAM 기능을 사용하여 최종 비트스트림의 필수 위치에 해당하는 트리의 위치에 있는 BitStream 요소에 저장된 출력 서브트리의 비트스트림을 생성하십시오.
    • DELETE문을 사용하여 가공을 완료한 경우 현재 입력 및 출력 레코드 메시지 트리를 모두 삭제하십시오.
    • 모든 레코드의 처리를 완료한 경우 출력 비트스트림에 나타나지 않도록 특수 폴더를 분리하십시오.
메시지에 필요한 프로세스에 맞게 이들 기술을 달리할 수 있습니다. 아래의 ESQL은 하나의 구현 예로써, 복합 XML 메시지 변환의 ESQL 예를 재작성한 것입니다. 중첩된 반복 구조의 메시지를 변환할 수 있는 중첩된 SELECT 함수가 있는 단일 SET문을 사용하십시오.
-- 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>
관련 개념
메시지 플로우 개요
ESQL 개요
관련 태스크
메시지 플로우 설계
메시지 플로우 컨텐츠 정의
ESQL 파일 관리
복합 XML 메시지 변환
관련 참조
Compute 노드
DELETE문
ASBITSTREAM 함수
메시지 예
주의사항 | 등록상표 | 다운로드 | 라이브러리 | 지원 | 피드백
Copyright IBM Corporation 1999, 2006 마지막 갱신 날짜: 2006/08/21
ac16740_