Oracle SQL*Loaderで関数と自動採番を使う
SQL*Loaderでデータをロードする際に、これまではCSV形式などをそのままロードする使い方だけでやっていました。
加工が必要な場合は、Perlなどで加工した後でロードしていました。でも、これだと無駄な1過程があるので、加工しながら直接ロードできるのではないか、ということでいくつか調べました。
詳細は参考URLを見ていただくのが早いですが、インデックスメモとして書いておきます。
実際に実行した環境のOracleバージョンは9iです。
サンプルとして、アクセスログのようなものを登録するデータベースを作ります。
まずはテーブル定義。
CREATE TABLE ACCESSLOG ( ACCESS_DATE CHAR(8), ACCESS_TIME CHAR(12), SEQ NUMBER(10), LOGMESSAGE VARCHAR(500), PRIMARY KEY (ACCESS_DATE,ACCESS_TIME,SEQ) )
登録するデータは以下のようなフォーマットのCSVファイル"accesslog.csv"です。
DATE:20110208,09:28:24.422,MSGAAA DATE:20110208,09:28:24.422,MSGAAA
制御ファイル(*.ctl)として、下記内容の"accesslog.ctl"を作ります。
LOAD DATA APPEND INTO TABLE ACCESSLOG FIELDS TERMINATED BY ',' TRAILING NULLCOLS ( ACCESS_DATE "SUBSTR(:ACCESS_DATE,-8,8)", ACCESS_TIME, SEQ SEQUENCE(MAX), LOGMESSAGE )
関数の評価結果を登録する場合は、上記の"SUBSTR"のようにします。ここでは、"ACCESS_DATE"の先頭に余計な文字が含まれているので、後ろから数えて8バイト目から8バイトだけを登録するようにします。
"SEQ"は、"ACCESS_DATE"と"ACCESS_TIME"だけではUNIQUEにならないので、自動採番しています。"SEQUENCE(MAX)"を指定すると、そのフィールドの最大値を自動的に埋めてくれます。よって必然的にUNIQUEになります。
実行するには、次のようにします。
$ sqlldr user/passwd@sysname control='accesslog.ctl' data='accesslog.csv' (メッセージ省略) $ sqlplus user/passwd@sysname (メッセージ省略) > SELECT * FROM ACCESSLOG; ACCESS_D ACCESS_TIME SEQ LOGMESSAGE -------- ------------ ---------- ----------------------------- 20110208 09:28:24.422 1 MSGAAA 20110208 09:28:24.422 2 MSGAAA >