技術ブログ
ちょっと余談的な話になりますが、外部表が使えない場合の一例として、SQL*Loaderからインスタンスにリモート接続する場合が挙げられます。SQL*Loaderを実行するのはデータベースサーバではなくてクライアントマシンですので、SQL*Loaderのデータファイル(ロード対象となるフラットファイル)は、クライアントマシンに配置されます。したがって、データファイルが置かれているディレクトリをディレクトリオブジェクトとして定義できません。
でも・・・
[oracle@l63x64b tmp]$ sqlldr rywatabe/rywatabe@C101TMP TABLE=emp
SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 20:34:00 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@l63x64b tmp]$ cat emp.log
SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 20:34:00 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 20:34:00 2013
実行終了火 8月 20 20:34:01 2013
実行時間: 00: 00: 00.99
CPU時間 : 00: 00: 00.02
[oracle@l63x64b tmp]$
しれっと正常ロードできてしまいました。でも何かおかしい・・・ もしや、クライアントマシンにあるデータファイルではなくて、データベースサーバにあるデータファイルをロードしているのでは・・・・
というわけで、データベースサーバにあったファイル(/var/tmp/emp.dat)をリネームしてから、再度同じコマンドを実行すると・・・
[oracle@l63x64b tmp]$ sqlldr rywatabe/rywatabe@C101TMP TABLE=emp
SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 20:34:56 2013
Copyright (c) 1982, 2013, Oracle and/or its affiliates. All rights reserved.
エクスプレス・モード・ロードの表: EMP
使用パス: 外部表, DEGREE_OF_PARALLELISM=AUTO
SQL*Loader-807: 表をロード中にエラーが発生しました
ORA-29913: ODCIEXTTABLEOPENコールアウトの実行中にエラーが発生しました。
ORA-29400: データ・カートリッジ・エラーが発生しました
KUP-04040: ファイルemp.datがSYS_SQLLDR_XT_TMPDIR_00000で見つかりません
表EMP:
0行のロードに成功しました。
確認するログ・ファイル:
emp.log
emp_%p.log_xt
ロードの詳細を参照してください。
[oracle@l63x64b tmp]$ cat emp.log
SQL*Loader: Release 12.1.0.1.0 - Production on 火 8月 20 20:34:56 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"
SQL*Loader-807: 表をロード中にエラーが発生しました
ORA-29913: ODCIEXTTABLEOPENコールアウトの実行中にエラーが発生しました。
ORA-29400: データ・カートリッジ・エラーが発生しました
KUP-04040: ファイルemp.datがSYS_SQLLDR_XT_TMPDIR_00000で見つかりません
外部表"SYS_SQLLDR_X_EXT_EMP"を削除しています
表EMP:
0行のロードに成功しました。
実行開始火 8月 20 20:34:56 2013
実行終了火 8月 20 20:34:56 2013
実行時間: 00: 00: 00.45
CPU時間 : 00: 00: 00.03
[oracle@l63x64b tmp]$
今度はエラー。リモート接続でSQL*Loaderを実行しても、データベースサーバ上のデータファイルにアクセスする? この動作・・・・微妙・・・・。