S-JIS[2012-07-07] 変更履歴

外部テーブル

Oracleの外部テーブル(external table)のメモ。


概要

external table(外部表)は、表領域(テーブルスペース)の外にテーブルのデータファイルを置き、テーブルとしてアクセスできるようにするもの。

データファイルはCSVファイルとDataPump(バイナリー)ファイルに対応している。
(DataPumpの方がCSVと違ってパース(構文解析)が必要ない分、速い?)

SQL*Loaderを使う場合、「データファイルを読み込んで対象テーブルにロードする」という動作になるが、
外部テーブルを使うと、「データファイルを外部テーブルとして定義し、そのテーブルから対象テーブルへSELECT-INSERTする」ということが出来る。
処理速度はSQL*Lodaerを使うより外部テーブルを使う方が速い。(インデックス無しのEMPテーブルへの100万件ロードなら3〜4倍くらい違う)

Oracle10gより前は外部テーブルは読み取り専用だったらしいが、Oracle10g以降は書き込みも出来るらしい。
とは言え、外部テーブルはあくまでSQL*Loaderのようなロードツールの補足機能らしいので、永続的なデータを置くべきではないだろう。
インデックスも作れないので、ランダムアクセスには向かないし。


外部テーブルの作成方法

ディレクトリーオブジェクトの作成

外部テーブルの実体となるデータファイルを置く場所は、Oracle DB内では「ディレクトリーオブジェクト」で管理される。

ディレクトリーオブジェクトは、管理者権限のあるユーザー(sys等)で作成する。

create or replace directory ディレクトリーオブジェクト名 as 'システム上のパス';
SQL> CREATE OR REPLACE DIRECTORY OLH_EXTTAB_DIR AS '/home/hishidama/oraloader/emp2';

Directory created.

そして、外部テーブルを作りたいユーザーに対し、ディレクトリーオブジェクトにアクセスできる権限を付ける必要がある。

grant read,write on directory ディレクトリーオブジェクト名 to ユーザー;
SQL> GRANT READ, WRITE ON DIRECTORY OLH_EXTTAB_DIR TO SCOTT;

Grant succeeded.

外部テーブルの作成

外部テーブルは、通常のCREATE文に、オプションとしてORGANIZATION EXTERNALを付ける。

create table テーブル名
(
 カラム定義…
)
organization external
(
 外部テーブル定義
);
プロパティー 内容
TYPE t アクセス・ドライバーの種類を指定する。
CSVファイルの場合:ORACLE_LOADER
DataPumpの場合:ORACLE_DATAPUMP
DEFAULT DIRECTORY d 実体のデータファイルの場所を示すディレクトリーオブジェクトを指定する。
ACCESS PARAMETERS アクセス・ドライバー用のパラメーターを設定する。
  RECORDS DELIMITED BY c レコードの区切り文字(改行コード)。
NEWLINEだとたぶんOSの改行コード(UNIXならLF)。
明示したい場合は「0x'0d0a'」の様に書く。
RECORDS FIXED n 固定長レコード。
CHARACTERSET encoding エンコーディング。
BADFILE file BADFILE(エラーがあったレコードを出力するファイル)のファイル名。
DISCARDFILE file 廃棄ファイルのファイル名。
LOGFILE file ログファイルのファイル名。
NOBADFILE BADFILEを出力しない。
NODISCARDFILE 廃棄ファイルを出力しない。
NOLOGFILE ログファイルを出力しない。
FIELDS TERMINATED BY c フィールド区切り文字。例:「','」「0x'09'
OPTIONALLY ENCLOSED BY c フィールドを囲む文字。例:「'"'
SKIP n たぶん、「SKIP 1」で1レコードスキップする。
STRING SIZES ARE IN CHARACTERS  
MISSING FIELD VALUES ARE NULL  
LOCATION file データファイルのファイル名。カンマ区切りで複数指定可能。

ファイル名は「'ファイル名'」の様に指定する。この場合、実際の(OS上の)ディレクトリーは「DEFAULT DIRECTORY」で指定したディレクトリーオブジェクトの指す場所になる。
ディレクトリーオブジェクト名:'ファイル名'」とすると、個別にディレクトリーを指定できる。

外部テーブルをCREATEする際は、指定したデータファイルが存在している必要は無い。
一度外部テーブルを作ると、データファイルの中身を書き換えれば、SELECTした際の値も自動的に変わる。


CSVファイルの例

CSVファイルの場合は、SQL*Loaderのコントロールファイルと同様のカラム定義を指定する。

CREATE TABLE  EXT_EMP2
(
   EMPNO                          NUMBER(4,0),
   ENAME                          VARCHAR2(10),
   JOB                            VARCHAR2(9),
   MGR                            NUMBER(4,0),
   HIREDATE                       DATE,
   SAL                            NUMBER(7,2),
   COMM                           NUMBER(7,2),
   DEPTNO                         NUMBER(2,0)
)
ORGANIZATION EXTERNAL
  (TYPE ORACLE_LOADER
   DEFAULT DIRECTORY OLH_EXTTAB_DIR
   ACCESS PARAMETERS
     (RECORDS DELIMITED BY NEWLINE
      CHARACTERSET AL32UTF8
      STRING SIZES ARE IN CHARACTERS
      FIELDS TERMINATED BY ','
          (
           EMPNO DECIMAL EXTERNAL,
           ENAME CHAR(10),
           JOB CHAR(9),
           MGR DECIMAL EXTERNAL,
           HIREDATE DATE "SYYYY-MM-DD HH24:MI:SS",
           SAL DECIMAL EXTERNAL,
           COMM DECIMAL EXTERNAL,
           DEPTNO DECIMAL EXTERNAL
          )
     )
   LOCATION ('oraloader-00000-csv-0.dat')
  );

Oracle Loader for HadoopでCSVファイルと外部表のCREATE文を作る


DataPumpファイルの例

CREATE TABLE  EXT_EMP2
(
   EMPNO                          NUMBER(4,0),
   ENAME                          VARCHAR2(10),
   JOB                            VARCHAR2(9),
   MGR                            NUMBER(4,0),
   HIREDATE                       DATE,
   SAL                            NUMBER(7,2),
   COMM                           NUMBER(7,2),
   DEPTNO                         NUMBER(2,0)
)
ORGANIZATION EXTERNAL
  (TYPE ORACLE_DATAPUMP
   DEFAULT DIRECTORY OLH_EXTTAB_DIR
   LOCATION ('oraloader-00000-dp-0.dat')
  );

Oracle Loader for HadoopでDataPumpファイルと外部表のCREATE文を作る


外部テーブル関連エラー

外部テーブルの使用に関するエラー。

select * from ext_emp2 where rownum <= 2
*
ERROR at line 1:
ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
error opening file /home/hishidama/oraloader/emp2/EXT_EMP2_12410.log

外部テーブルを使用する際は、ログファイル等を書き込む場所に(UNIXの)oracleユーザーの書込権限が必要。
(たぶん、Oracleプロセスを実行しているUNIXユーザーがoracle)

そのディレクトリー(ディレクトリーオブジェクトが指している実際の場所)に対してoracleユーザーへの書込権限を付けるか、
書き込もうとしているファイルを書き込まない設定にする。(例えばNOLOGFILEを指定するとログファイルは出力されなくなる)


テーブルへ戻る / SQLメモへ戻る / Oracle目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま