技術ブログ
ちょっと余談的な話になりますが、外部表が使えない場合の一例として、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を実行しても、データベースサーバ上のデータファイルにアクセスする? この動作・・・・微妙・・・・。