14.3 データをLOBにロードするためのデータベース・ユーティリティ

データベースの設定またはメンテナンス・タスクの一部としてデータをLOB列にバルク・ロードする場合は、特定のユーティリティの使用をお薦めします。

データベースのセットアップまたはメンテナンス・タスクの一環としてデータをLOB列にバルク・ロードするには、次のユーティリティの使用をお薦めします。

  • SQL*Loader
  • 外部表
  • Oracle Data Pump

14.3.1 SQL*Loaderを使用したLOBのロード

ダイレクト・パス・ロードの使用が推奨される場合の従来型ロードとダイレクト・パス・ロード、および問題を回避するために従う必要があるルールとガイドラインについて学習します。

ラージ・オブジェクト(LOB)データをロードするには、次の2つのオプションがあります。

従来型パスによるロードは、SQL INSERT文を実行して、表をOracle Databaseに移入します。

ダイレクト・パス・ロードは、Oracleデータ・ブロックをフォーマットし、データ・ブロックを直接データベース・ファイルに書き込むことによって、Oracle Databaseのオーバーヘッドの大半を排除します。また、ダイレクト・パス・ロードでは、データベース・リソースに対して他のユーザーとの競合が発生しないため、ディスク速度に近い速度でデータをロードできます。ダイレクト・パス・ロードには、その他の制限、セキュリティおよびバックアップの影響もあることに注意してください。これらは確認する必要があります。

ラージ・オブジェクト・データ(LOB)をロードするこれらのオプションごとに、次の方法を使用してLOBにデータをロードできます。

  • プライマリ・データ・ファイルからのLOBデータのロード。

    プライマリ・データ・ファイルからデータをロードする場合、LOB列のデータは、ロードするファイル内のレコードの一部になります。

  • LOBファイルを使用したセカンダリ・データファイルからのLOBデータのロード。

    セカンダリ・データファイルからデータをロードする場合、LOB列のデータはプライマリ・データファイルとは異なるファイルにあります。プライマリ・データ・ファイルには、データ自体ではなく、他のファイルのLOBデータの内容の場所に関する情報が含まれています。

SQL*Loaderを使用したLOBのロードに関する推奨事項

SQL*Loaderを使用してLOBをロードする際に、次のガイドラインおよびルールに留意することをお薦めします。

  • ロードする表は、すでにデータベースに存在する必要があります。SQL*Loaderでは、表は作成されません。データが含まれているか、または空である既存の表にロードされます。

  • LOBファイルからデータをロードする場合は、LOB型の列に対応するフィールドの最大長を指定します。最大長が指定されている場合、SQL*Loaderはこの長さをヒントとして使用し、メモリー使用量の最適化に役立てます。指定する最大長が実際の最大長を過少評価しないようにしてください。

  • 従来型パスによるロードを使用する場合、特定のLOBのロードに失敗しても、そのLOBを含むレコードは拒否されないことに注意してください。かわりに、レコードには空のLOBが含まれます。

  • ダイレクト・パス・ロードを使用する場合は、LOBのロードに大量のメモリーが使用される可能性があることに注意してください。LOBのロード時に、メッセージSQL*Loader 700 (メモリー不足)が発生した場合、内部コードによってロードのコール1回当たりにバッチされる行の数が、オペレーティング・システムおよびプロセス・メモリーのサポートする数を超えている可能性があります。この問題を回避する1つの方法は、ROWSオプションを使用して、各データ・セーブで読み取る行数を少なくすることです。

    CLOBSとして格納されているXMLtype列に有効であることがわかっているXML文書をロードするには、ダイレクト・パス・ロードのみを使用します。ダイレクト・パス・ロードでは、CLOBとしてロードされるため、XML文書の形式は検証されません。

    ダイレクト・パス・ロードでは、エラーがクリティカルになる可能性があります。ダイレクト・パス・ロードでは、LOBがであるか切り捨てられる可能性があります。LOBは、ロード時にピース単位でサーバーに送信されます。LOBピースにエラーがある場合、そのピースは廃棄され、そのLOBの残りはロードされません。その結果、エラーのあるLOB全体が最初のピースに含まれている場合、そのLOB列は空または切り捨てられます。

    ダイレクト・パスAPIを使用して、LOBをロードすることもできます。

SQL*Loaderを使用したLOBのロードに必要な権限

SQL*Loaderを使用してLOBをロードするには、次の権限が必要です。

  • ロードする表に対するINSERT権限が必要です。

  • 新しいデータをロードする前に、REPLACEまたはTRUNCATEオプションを使用して古いデータを空にする場合は、ロードする表に対するDELETE権限が必要です。

例14-1 デリミタ付きフィールドを使用したプライマリ・データファイルからのLOBのロード

この例を確認して、デリミタ付きフィールドにLOBデータをロードする方法を理解してください。太字のコールアウト「1」および「2」に注目してください。

制御ファイルの内容

LOAD DATA 
INFILE 'sample.dat' "str '|'"
INTO TABLE person_table
FIELDS TERMINATED BY ','
   (name        CHAR(25),
1  "RESUME"     CHAR(507) ENCLOSED BY '<startlob>' AND '<endlob>')

データ・ファイル(sample.dat)

Julia Nayer,<startlob>        Julia Nayer
                          500 Example Parkway
                          jnayer@example.com ...   <endlob>
2  |Bruce Ernst, .......

ノート:

例の左に付けた太字の数字は、次のノートと対応しています。

  1. <startlob>および<endlob>は、囲み文字列です。デフォルトのバイト長セマンティクスでは、CHAR(507)を使用して読み込むことができるLOBの最大長は507バイトです。文字長セマンティクスが使用された場合、最大長は507文字になります。詳細は、文字長セマンティクスを参照してください。

  2. レコード・セパレータ'|'は、<endlob>のすぐ後にあり、その後に改行文字が続く場合、改行は、次のレコードの一部として解釈されます。代替方法は、レコード・セパレータに改行部分を作成することです(たとえば'|\n'、または16進ではX'7C0A')。

例14-2 デリミタ付きフィールドを使用したセカンダリ・データ・ファイルからのLOBのロード

この例では、コールアウト「1」が太字で示されています。

制御ファイルの内容

LOAD DATA 
INFILE 'sample.dat'
INTO TABLE person_table
FIELDS TERMINATED BY ','
   (name     CHAR(20),
1  "RESUME"    LOBFILE( CONSTANT 'jqresume') CHAR(2000) 
               TERMINATED BY "<endlob>\n")

データ・ファイル(sample.dat)

Johny Quest,
Speed Racer,

セカンダリ・データ・ファイル(jqresume.txt)

             Johny Quest
         500 Oracle Parkway
            ... <endlob>
             Speed Racer
         400 Oracle Parkway
            ... <endlob>

ノート:

例の左に付けた太字の数字は、次のノートと対応しています。

  1. CHARの最大長に2000が指定されているため、SQL*Loaderで、フィールドの最大長を推測でき、メモリーの使用量を最適化できます。最大長を指定する場合、小さすぎる値は指定しないように注意してください。TERMINATED BY句は、LOBを終了する文字列を指定します。かわりに、ENCLOSED BY句も使用できます。ENCLOSED BY句を使用すると、LOBFILE内のLOBの相対的な配置により柔軟性が少し高まります。これは、LOBFILE内のLOBが連続している必要がないためです。

14.3.2 SQL*Loaderを使用したBFILEのロード

この項では、SQL*Loaderを使用してファイル・システム内のファイルからBFILE列にデータをロードする方法について説明します。

ノート:

  • BFILEデータ型には、データベースの外側にあるオペレーティング・システム・ファイルの非構造化バイナリ・データが格納されます。BFILE列または属性には、データを含むサーバー側外部ファイルを示すロケータが格納されます。
  • BFILEとしてロードされるファイルは、ロード時に実際に存在する必要はありません。SQL*Loaderでは、必要なディレクトリ・オブジェクトは作成済であるとみなされます。

関連項目:

詳細は、ディレクトリ・オブジェクトを参照してください

BFILE列に対応する制御ファイル・フィールドは、列名およびそれに続くBFILEディレクティブで構成されます。

BFILEディレクティブは、DIRECTORYオブジェクト名およびそれに続けてBFILE名を引数としてとります。これらは、文字列定数として指定するか、その他のフィールドを介して動的にソース名を指定できます。

関連項目:

SQL*Loader構文の詳細は、『Oracle Databaseユーティリティ』を参照してください。

次の2つの例では、BFILEのロードを示します。

ノート:

特定の例が機能するには、次のデータ構造を設定する必要があります。

CONNECT pm/pm
CREATE OR REPLACE DIRECTORY adgraphic_photo as '/tmp';
CREATE OR REPLACE DIRECTORY adgraphic_dir as '/tmp';

次の例では、ファイル名のみが動的に指定されます。ディレクトリ名adgraphic_photoは引用符で囲まれています。したがって、文字列はそのまま使用され、大文字ではありません。

制御ファイル:

LOAD DATA
INFILE sample9.dat
INTO TABLE Print_media
FIELDS TERMINATED BY ','
(product_id  INTEGER EXTERNAL(6),
 FileName    FILLER CHAR(30),
 ad_graphic  BFILE(CONSTANT "adgraphic_photo", FileName))

データ・ファイル:

007, modem_2268.jpg,
008, monitor_3060.jpg,
009, keyboard_2056.jpg,

次の例では、BFILEおよびディレクトリ・オブジェクトが動的に指定されます。

制御ファイル:

LOAD DATA
INFILE sample10.dat
INTO TABLE Print_media
FIELDS TERMINATED BY ','
(
 product_id INTEGER EXTERNAL(6),
 ad_graphic BFILE (DirName, FileName),
 FileName  FILLER CHAR(30),
 DirName   FILLER CHAR(30)
)

データ・ファイル:

007,monitor_3060.jpg,ADGRAPHIC_PHOTO,
008,modem_2268.jpg,ADGRAPHIC_PHOTO,
009,keyboard_2056.jpg,ADGRAPHIC_DIR,

14.3.3 外部表を使用したLOBのロード

外部表は、単一のファイルから多数のレコードをロードし、各レコードが表の独自の行になるようにする場合に特に役立ちます。

14.3.3.1 LOBおよび外部表の概要

データベースで外部表を使用してデータの読取りおよび書込みを行う利点と、その作成方法を学習します。

外部表を使用すると、外部ファイルの内容をOracle Databaseの表の行として扱うことができます。外部表を作成したら、SQL文を使用して外部表から行を読み取り、別の表に挿入できます。

これらの操作を実行するために、Oracle Databaseは次のいずれかのアクセス・ドライバを使用します。

  • ORACLE_LOADERアクセス・ドライバは、SQL Loaderと同様に、テキスト・ファイルおよびその他のファイル形式を読み取ります。
  • ORACLE_DATAPUMPアクセス・ドライバは、問合せによって返されたデータを格納するバイナリ・ファイルを作成します。また、ファイルから行をバイナリ形式で返します。

外部表を作成するときは、外部表の列およびデータ型を指定します。アクセス・ドライバは、データ・ファイルに列のリストを持ち、データ・ファイルのフィールドの内容を外部表の同じ名前の列にマップします。アクセス・ドライバは、データ・ソース内のフィールドを検索し、これらのフィールドを外部表内の対応する列の適切なデータ型に変換します。外部表を作成した後、INSERT AS SELECT文を使用してターゲット表をロードできます。

外部表を使用してデータをSQL Loaderと比較してロードする利点の1つは、外部表がデータをパラレルにロードできることです。これを行う最も簡単な方法は、PARALLEL句を外部表とターゲット表の両方のCREATE TABLEの一部として指定することです。

例14-3

この例では、外部表でロードできる表CANDIDATEを作成します。ロードされると、外部表CANDIDATE_XTが作成されます。次に、INSERT文を実行して表をロードします。INSERT文には、ダイレクト・ロードを使用して表CANDIDATESに行を挿入する+APPENDヒントが含まれています。PARALLELパラメータは、表にパラレルでアクセスできることをSQLに通知します。

PARALLELパラメータ設定では、CANDIDATE_XTから読み取るパラレル問合せプロセスを4つ(4)指定し、CANDIDATEに挿入するパラレル・プロセスを4つ指定できます。BASICFILEとして格納されているLOBはパラレルでロードできないことに注意してください。SECUREFILE LOBSはパラレルでのみロードできます。変数additional-external-table-infoは、追加の外部表情報を挿入できる場所を示します。

CREATE TABLE CANDIDATES

  (candidate_id       NUMBER,

   first_name         VARCHAR2(15),

   last_name          VARCHAR2(20),

   resume             CLOB,

   picture            BLOB

  ) PARALLEL 4;


CREATE TABLE CANDIDATE_XT

  (candidate_id       NUMBER,

   first_name         VARCHAR2(15),

   last_name          VARCHAR2(20),

   resume             CLOB,

   picture            BLOB

  ) PARALLEL 4;

ORGANIZATION EXTERNAL additional-external-table-info PARALLEL 4; 

INSERT /*+APPEND*/ INTO CANDIDATE SELECT * FROM CANDIDATE_XT;

アクセス・ドライバによって作成された外部表のファイルの場所

ORACLE_LOADERおよびORACLE_DATAPUMPによって作成または読み取られたすべてのファイルは、ディレクトリ・オブジェクトが指すディレクトリにあります。DBAまたはCREATE DIRECTORY権限を持つユーザーは、新しいオブジェクトをファイル・システム上のパスにマップするディレクトリ・オブジェクトを作成できます。これらのユーザーは、作成されたディレクトリ・オブジェクトに対するREADWRITEまたはEXECUTE権限を他のユーザーに付与できます。ディレクトリ・オブジェクトに対するREAD権限を付与されたユーザーは、外部表を使用して、ディレクトリ・オブジェクトのディレクトリからファイルを読み取れます。同様に、ディレクトリ・オブジェクトに対するWRITE権限を持つユーザーは、外部表を使用して、ディレクトリ・オブジェクトのディレクトリにファイルを書き込めます。

例14-4 ディレクトリ・オブジェクトの作成

次の例では、ディレクトリ・オブジェクトを作成し、READおよびWRITEアクセス権をユーザーHRに付与する方法を示します。

create directory HR_DIR as /usr/hr/files/exttab;

grant read, write on directory HR_DIR to HR;

ノート:

Oracle Real Application Clusters (Oracle RAC)環境で外部表を使用する場合は、ディレクトリ・オブジェクトが指すディレクトリが、すべてのノードからアクセス可能なディレクトリにマップされていることを確認する必要があります。