技術ブログ
Oracle Database 12cよりSQL*Loader にExpress Modeと呼ばれる制御ファイルなしで データを簡単にローディングできる手段が提供されました。使用方法は簡単でsqlldrにTABLEパラメータを指定するだけです。
SQL> CREATE TABLE EMP 2 (EMPNO number(4) not null, 3 ENAME varchar2(10), 4 HIREDATE date, 5 DEPTNO number(2)); 表が作成されました。
[oracle@l63x64a tmp]$ cat emp.dat 7782,Clark,81-06-09,10 7839,King,81-11-17,12
パラメータ値と同名のテーブルとCSVファイルを用意しておくと、以下のコマンド 一発でロードが可能です。摩訶不思議なSQL*Loadre制御ファイルの文法と格闘しなくてもよいので、 個人的ななかなかうれしい新機能です。
[oracle@l63x64a tmp]$ sqlldr rywatabe/rywatabe TABLE=emp SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 05:21:15 2013 Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved. エクスプレス・モード・ロードの表: EMP 使用パス: 外部表, DEGREE_OF_PARALLELISM=AUTO 表EMP: 2行のロードに成功しました。 確認するログ・ファイル: emp.log emp_%p.log_xt ロードの詳細を参照してください。
ログファイルを覗いていみるとちょっと面白いことがわかります。
[oracle@l63x64a tmp]$ cat emp.log
SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 05:24:38 2013
Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved.
エクスプレス・モード・ロードの表: EMP
データファイルemp.dat
不良ファイル: emp_%p.bad
廃棄ファイル: 指定なし
(すべて廃棄できます)
ロード数: ALL
スキップ数: 0
許容エラー数: 50
継続文字: 指定なし
使用パス: 外部表
表EMP、 ロード済 すべての論理レコードから
この表に対する有効な挿入オプション: APPEND
列名 位置 長さ 用語暗号化データ型
------------------------------ ---------- ----- ---- ---- ---------------------
EMPNO FIRST * , CHARACTER
ENAME NEXT * , CHARACTER
HIREDATE NEXT * , DATE "RR-MM-DD"
DEPTNO NEXT * , CHARACTER
可能性のある再使用のために生成された制御ファイル:
OPTIONS(EXTERNAL_TABLE=EXECUTE, TRIM=LRTRIM)
LOAD DATA
INFILE 'emp'
APPEND
INTO TABLE EMP
FIELDS TERMINATED BY ","
(
EMPNO,
ENAME,
HIREDATE DATE,
DEPTNO
)
可能性のある再使用のために生成された制御ファイルの終わり。
一時ディレクトリ・オブジェクトSYS_SQLLDR_XT_TMPDIR_00000がパス/var/tmpに対して作成されました
パラレルDML: ALTER SESSION ENABLE PARALLEL DMLを有効化します
外部表"SYS_SQLLDR_X_EXT_EMP"を作成しています
CREATE TABLE "SYS_SQLLDR_X_EXT_EMP"
(
"EMPNO" NUMBER(4),
"ENAME" VARCHAR2(10),
"HIREDATE" DATE,
"DEPTNO" NUMBER(2)
)
ORGANIZATION external
(
TYPE oracle_loader
DEFAULT DIRECTORY SYS_SQLLDR_XT_TMPDIR_00000
ACCESS PARAMETERS
(
RECORDS DELIMITED BY NEWLINE CHARACTERSET AL32UTF8
BADFILE 'SYS_SQLLDR_XT_TMPDIR_00000':'emp_%p.bad'
LOGFILE 'emp_%p.log_xt'
READSIZE 1048576
FIELDS TERMINATED BY "," LRTRIM
REJECT ROWS WITH ALL NULL FIELDS
(
"EMPNO" CHAR(255),
"ENAME" CHAR(255),
"HIREDATE" CHAR(255)
DATE_FORMAT DATE MASK "RR-MM-DD",
"DEPTNO" CHAR(255)
)
)
location
(
'emp.dat'
)
)REJECT LIMIT UNLIMITED
INSERT文を実行してデータベース表EMPをロードしています
INSERT /*+ append parallel(auto) */ INTO EMP
(
EMPNO,
ENAME,
HIREDATE,
DEPTNO
)
SELECT
"EMPNO",
"ENAME",
"HIREDATE",
"DEPTNO"
FROM "SYS_SQLLDR_X_EXT_EMP"
外部表"SYS_SQLLDR_X_EXT_EMP"を削除しています
表EMP:
2行のロードに成功しました。
実行開始火 8月 20 05:24:38 2013
実行終了火 8月 20 05:24:39 2013
実行時間: 00: 00: 01.02
CPU時間 : 00: 00: 00.03
見ての通りデータファイルが配置されているディレクトリに一時ディレクトリオブジェクトを作成し、データファイルをデータソースに指定した外部表を作成し、INSERT AS SELECTでデータをローディングしているようです。このデータローディング方法の方が、SQL*Loaderダイレクトパスロードよりも高速ということでしょうか? 興味深いためメモしておきます。