彈性檔案名稱/寫入多個檔案

依預設,資料會寫入批次參數中定義的「檔案名稱」。檔案名稱支援數個動態替代變數,如「外掛導向擷取範本」批次控制 (F1-PDBEX) 批次參數的詳細描述中所定義。另請參考擷取記錄處理,以取得檔案名稱與多執行緒處理的相關資訊。

系統還支援為單一批次執行建立更進階的檔案。請考量下列使用案例

  • 擷取對象是與多個服務提供者相關聯的資料,而每個服務提供者應收到自己的檔案。在此使用案例中,工作單位為服務提供者,因此會為每個工作單位產生一個檔案。
  • 實作與「客戶資訊系統分區」所代表的多個管轄地共同運作。特定擷取應為每個分區產生一個檔案,讓每個分區僅取得其相關資料。
  • 「人員」資訊的擷取應將個別人員資料與業務人員資料分開。此外,針對每位人員,聯絡資訊應產生個別的檔案。在此使用案例中,一個工作單位包含要寫入多個檔案的資料。

為支援上述使用案例,「處理記錄」演算法支援在輸出中傳回「檔案名稱」:

  • 檔案名稱包含在輸出「結構實例」群組中。如果您希望特定「結構」項目的資料使用此檔案名稱,請植入此值。在上述的人員擷取範例中,包含聯絡資訊的結構會指出特定的聯絡資訊檔案。
  • 檔案名稱是結構列表以外的輸出欄位。如果您沒有不同結構的其他檔案,但仍要置換批次參數中定義的檔案名稱,則植入此欄位。上述服務提供者與分區範例會使用所需的檔案名稱植入此參數。人員擷取範例可針對所有非聯絡資訊植入此欄位。

批次處理會在每次呼叫「處理記錄」演算法後檢查輸出。對於每個結構,如果有特定的檔案名稱與此結構相關聯,系統會將結構的資料寫入該檔案。如果提供輸出檔案名稱,則資料寫入該輸出檔案。否則,會使用批次參數中的檔案名稱。

備註:替代變數。在呼叫「處理記錄」後,若檔案名稱中有任何系統變數,此時會解析這些變數。

管理檔案名稱

此類型的需求表示「處理記錄」演算法需要提供具有某個業務值的檔案名稱來區分個別檔案。例如,服務提供者、分區或人員類型值必須為檔案名稱的一部分。不過,建議不要完全由演算法決定檔案名稱。建議的作法是仍允許使用者提交批次工作,以提供所需的檔案名稱作為批次參數。如此一來,它就能包含系統資訊 (例如批次執行編號或日期/時間戳記) 的所有支援替代變數,確保您的檔案對指定批次執行是唯一的。演算法可以指定它所尋找的替代變數取代為業務值。

例如,使用每個分區的檔案這個使用案例時,假設使用者指示了檔案名稱 EXTRACT_​FILE_​<DIV>_​{BN}_​{RN}_​{TN}.csv。處理記錄演算法收到此參數。它知道要尋找的是 "<DIV>",並將其取代為實際的分區。假設分區代碼為 A100,演算法會在其輸出中為此工作單位傳回檔案名稱 EXTRACT_​FILE_​A100_​{BN}_​{RN}_​{TN}.csv,以及要寫入該檔案的資料。

以上述人員資訊使用案例來說,當中寫入了兩個檔案,建議其中一個檔案 (例如人員資訊檔案) 使用「檔案名稱」參數。第二個檔案 (聯絡資訊檔案) 則應使用其他參數來定義。因此,提交批次工作的使用者會定義下列參數:

參數名稱 描述 註釋
fileName 檔案名稱 persons_​<personType>_​{BN}.txt 這是隨擷取提供的檔案名稱參數。
contactFileName 聯絡資訊檔案名稱 contacts_​{BN}.txt 此為 CM 擷取批次控制所定義的特殊參數。

「處理記錄」演算法會尋找提供作為輸入的「檔案名稱」參數,找到文字 "<personType>",並將其取代為人員類型值,然後在輸出中傳回該檔案名稱。建立要在輸出中傳回的結構列表時,包含人員聯絡資訊的結構列表會包含提供作為輸入的「聯絡資訊檔案名稱」參數中找到的檔案名稱。

備註:如果擷取使用檔案整合類型,則檔案整合記錄的擷取處理演算法負責上述事項,也就是指出檔案名稱並將其傳回「處理記錄」演算法。

多個執行緒

此功能如預期般可使用多個執行緒進行作業。根據「選取記錄」演算法的使用案例與實作,每個執行緒可對相同業務值產生檔案。讓我們使用分區使用案例。假設實作含有三個分區:A100、B200、C300。現在,假設擷取對象是帳戶的財務資訊。選取記錄演算法應依帳戶 ID 進行執行緒處理,如此才能在多個執行緒間平均分配資料。但在每個執行緒中,帳戶可能屬於 3 個實作分區中的任一分區。因此,每個執行緒可以為這 3 個分區的每一個分區產生 3 個檔案。

多執行緒擷取中所述,系統支援串連選項,可讓您合併檔案,因此您會有 3 個分區的 3 個完整檔案。該主題中描述的相同功能和限制適用於此使用案例。

關閉檔案

使用此功能時,重要考量事項是您務必要注意批次處理期間所開啟的檔案數目。每個開啟的檔案都會用到一些記憶體來加以管理。因此,產品會強制實行在批次工作執行期間只能有 10 個已開啟檔案 (每一執行緒) 的限制。將批次設計成寫入多個檔案時,本產品強烈建議您設計處理,以在任何可能的情況下,只要將一個檔案的所有資料都寫入後,就能關閉該檔案,然後再移至下一個檔案。

讓我們看看以下範例。

  • 以服務提供者為例,批次處理的工作單位就是服務提供者。在此案例中,每次呼叫處理記錄後,系統可將資料寫入檔案,然後就能關閉檔案。
  • 以分區為例,選取的資料應該依與擷取目的 (例如「帳戶」或「資產」) 相關的適當工作單位進行執行緒處理。但資料應依分區排序,這樣各分區的所有資料都處理完後,才會處理下一個分區的資料。開始處理下一個分區的資料後,各分區的檔案即可關閉。
  • 以人員擷取為例,聯絡資訊檔案可用於所有資料,因此該檔案在整個工作期間都需要維持開啟狀態。不過,人員資訊會依人員類型劃分。「選取記錄」可依人員類型排序資料,如此便能寫入某類型的所有資料後,接著再寫入其他類型的所有資料。然而,由於任何執行都不會開啟超過 3 個檔案,因此此使用案例在處理期間不需要主動管理關閉檔案。

批次程式要如何知道何時關閉檔案?由於批次程式不受干擾,且不知道正在處理的資料類型或何時應關閉檔案,因此「處理記錄」演算法應提供此資訊。

備註:如果「處理記錄」指出要寫入的檔案是已關閉的檔案,批次處理就會發出錯誤。不允許重新開啟已關閉的檔案。如果收到此錯誤,則需要複查處理設計。

為處理此情況,批次處理提供「處理記錄」演算法與已開啟檔案列表 (未解析系統替代變數),以及一個布林來標示是否應該關閉檔案。

備註:如果擷取使用檔案整合類型,則檔案整合記錄的擷取處理演算法會收到此已開啟檔案列表,且負責此處所述的管理關閉檔案。

在此將使用我們的範例做進一步的說明。

每個分區的檔案範例

此使用案例是實作中有 4 個分區:NORTH、EAST、SOUTH、WEST,而資料 (帳戶資料) 應依分區群組在個別的檔案中。

建議的做法是「選取記錄」演算法選取依「分區」排序的資料。

批次處理會傳遞已開啟檔案列表 (應該只有零個或一個檔案) 給「處理記錄」演算法。在此案例中,唯一的指示是如果「處理記錄」演算法發現其資料屬於某一分區,但列出的已開啟檔案屬於不同的分區,此時就算完成一個分區的資料。每個呼叫都應準備其檔案名稱。接著呼叫應查看其檔案名稱是否在已開啟檔案列表中。如果不在其中,則它需要指示應關閉其他開啟的檔案。(請注意,它不需要將自己新增至「開啟列表」。批次程式僅會尋找標示為已關閉的項目。它會忽略未標示為已關閉的項目。)

假設批次參數中的檔案名稱是 myFile_​<DIV>_​{BN}.txt

系統會排序資料,以便先處理 EAST 分區中的帳戶。假想這是一個工作單位,而它同時也在 EAST 分區中。它收到檔案名稱和已開啟檔案列表。

...
<hard>
<batchParms>
  <BatchParm>
    <name>fileName</name>
    <value>myFile_<DIV>_{BN}.txt</value>
  </BatchParm>
  ...
</batchParms>
<openFiles>
  <OpenFile>
    <closeFile></closeFile>
    <fileName>myFile_EAST_{BN}.txt</fileName>
  </OpenFile>
</openFiles>
...
</hard>

演算法將其分區取代為檔案的 <DIV> 部分,並在輸出中植入該值。接著它將其檔案名稱與目前已開啟檔案列表進行比較。演算法找到了它的檔案,因此不需要執行其他任何作業。


<hard>
...
<fileName>myFile_EAST_{BN}.txt</fileName>
...
<openFiles>
  <OpenFile>
    <closeFile></closeFile>
    <fileName>myFile_EAST_{BN}.txt</fileName>
  </OpenFile>
</openFiles>
...
</hard>

如果我們接著假設呼叫處理記錄演算法,其中分區為 NORTH,此演算法是該分區的第一個項目,以下是它收到的資訊:


<hard>
<batchParms>
  <BatchParm>
    <name>fileName</name>
    <value>myFile_<DIV>_{BN}.txt</value>
  </BatchParm>
  ...
</batchParms>
<openFiles>
  <OpenFile>
    <closeFile>true</closeFile>
    <fileName>myFile_EAST_{BN}.txt</fileName>
  </OpenFile>
</openFiles>
...
</hard>

演算法將其分區取代為檔案的 <DIV> 部分,並在輸出中植入該值。接著演算法將其檔案名稱與目前已開啟檔案列表進行比較,但找不到其檔案名稱。因此,它指出應該關閉現有已開啟檔案。


<hard>
...
<fileName>myFile_NORTH_{BN}.txt</fileName>
...
<openFiles>
  <OpenFile>
    <closeFile>true</closeFile>
    <fileName>myFile_EAST_{BN}.txt</fileName>
  </OpenFile>
</openFiles>
...
</hard>

每一服務提供者的檔案範例

在此使用案例中,工作單位為服務提供者,每個服務提供者都應該有自己的檔案。在此案例中,「處理記錄」演算法在準備資料時,發現檔案名稱對其服務提供者而言是唯一的,它也能指示可將檔案關閉。而不需要等待下次呼叫「處理記錄」來指示可以關閉上一個檔案。假設檔案名稱是 MYFILE_​<serviceProvder>_​{BN}_​{TN}.txt。每次呼叫「處理記錄」時,系統將會傳遞批次參數檔名稱,不會有檔案開啟的狀況發生。


<hard>
<batchParms>
  <BatchParm>
    <name>fileName</name>
    <value>MYFILE_<serviceProvider>_{BC}_{TN}.txt</value>
  </BatchParm>
  ...
</batchParms>
<openFiles>
  <OpenFile>
    <fileName></fileName>
    <closeFile></closeFile>
  </OpenFile>
</openFiles>
...
</hard>

演算法處理服務提供者 A100 的資料。它傳回下列與檔案名稱 (即與此服務提供者相關之輸出中的單一檔案名稱) 相關的資訊,然後將其檔案新增至已開啟檔案列表中,並指示應將檔案關閉。(請注意,每一工作單位的檔案是演算法會知道它是檔案的最後一個項目並自行關閉檔案的唯一已知使用案例。)

<hard>
...
<fileName>MYFILE_A100_{BC}_{TN}.txt</fileName>
...
<openFiles>
  <OpenFile>
    <closeFile>true</closeFile>
    <fileName>MYFILE_A100_{BC}_{TN}.txt</fileName>
  </OpenFile>
</openFiles>
...
</hard>

多個已開啟檔案範例

此範例假設檔案名稱是依據上述的「管理檔案名稱」區段所定義。我們會假設演算法設計者選擇不主動關閉人員資訊檔案,因為開啟的檔案絕對不超過三個。同樣地,我們假設他們選擇不依人員類型排序資料。以下是在執行過程中傳入的資訊:

<hard>
<batchParms>
  <BatchParm>
    <name>fileName</name>
    <value>persons_<personType>_{BN}.txt</value>
  </BatchParm>
  <BatchParm>
    <name>contactFileName</name>
    <value>contacts_{BN}.txt</value>
   </BatchParm>
  ...
</batchParms>
<openFiles>
  <OpenFile>
    <fileName>persons_P_{BN}.txt</fileName>
    <closeFile></closeFile>
  </OpenFile>
   <OpenFile>
    <fileName>persons_B_{BN}.txt</fileName>
    <closeFile></closeFile>
  </OpenFile>
  <OpenFile>
    <fileName>contacts_{BN}.txt</fileName>
    <closeFile></closeFile>
  </OpenFile>
</openFiles>
...
</hard>

實例為一個「處理記錄」演算法的呼叫,該演算法具有個人 (人員類型為 "P") 的明細。


<fileName>persons_P_{BN}.txt</fileName> 
<fileOutput>
  <listValue>
    <SchemaInstance>
      <recordXMLNode>person</recordXMLNode>
      <schemaName>CM-PersonDetail</schemaName>
      <schemaType>F1SS</schemaType>
      <fileName></fileName>
      <data>LotsOfData</data>
    </SchemaInstance>
  </listValue>
  <listValue>
    <SchemaInstance>
      <recordXMLNode>person</recordXMLNode>
      <schemaName>CM-AddressDetail</schemaName>
      <schemaType>F1SS</schemaType>
      <fileName></fileName>
      <data>LotsOfData</data>
    </SchemaInstance>
  </listValue>
  <listValue>
    <SchemaInstance>
      <recordXMLNode></recordXMLNode>
      <schemaName>CM-ContactDetail</schemaName>
      <schemaType>F1SS</schemaType>
      <fileName>contacts_{BN}.txt</fileName>
      <data>LotsOfData</data>
    </SchemaInstance>
  </listValue>
</fileOutput>

此 XML 範例說明下列各點:

  • fileName 元素中有一個置換檔案名稱。
  • 前兩個結構在 fileOutput\listValue\SchemaInstance\fileName 中沒有任何值,因此應該將它們寫入 fileName 中的檔案。請注意,這兩個結構也包含「記錄 XML 節點」。這會確保如果輸出為 XML 格式,這兩個結構的資料都會由「人員 XML 節點」包裹。此 Epic 與功能無關。它只是嘗試說明多個功能。
  • 第三個結構在 fileOutput\listValue\SchemaInstance\fileName 中有一個項目。因此,該資料會寫入到個別的檔案。