2015年6月28日日曜日

[Oracle12c]SQL*Loaderのエクスプレス・モード

Oracle12CからはSQL*Loaderのエクスプレス・モードを使用してコントロールファイルを作らずにデータをロードすることができるようです。
この機能は、表の列がすべて文字列、数値または日付型で、入力ファイルにデリミタ付きの文字列データが含まれている場合(例えばCSVファイル)に、テーブル名の指定のみでロードが実行できます。

エクスプレスモードの例

テーブル定義

主キーと属性1つづつのシンプルなテーブルで試してみます。
SQL> desc users;
 Name        Null?    Type
 ----------------------------------------- -------- ----------------------------
 USER_ID       NOT NULL NUMBER(10)
 NAME          VARCHAR2(100 CHAR)

CSVファイルの内容

データが5行のCSVファイルです。
1,user1
2,user2
3,user3
4,user4
5,user5

実行結果

実行結果の標準出力内容です。5行のロードが正常に終わっていることがわかります。
実行時には、接続情報をテーブル名のみを与えるのみで、コントロールファイルは作成していません。
入力ファイルを指定しない場合、デフォルトでは「テーブル名.dat」となります。今回の場合は、「users.dat」が入力ファイルとなります。
$ sqlldr hoge/hoge@orcl TABLE=users

SQL*Loader: Release 12.1.0.2.0 - Production on Sat Jun 27 10:49:48 2015

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Express Mode Load, Table: USERS
Path used:      External Table, DEGREE_OF_PARALLELISM=AUTO

Table USERS:
  5 Rows successfully loaded.

Check the log files:
  users.log
  users_%p.log_xt
for more information about the load.

テーブルにも5レコード格納されています。
SQL> r
  1* select * from users

   USER_ID NAME
---------- -------------------------
  1 user1
  2 user2
  3 user3
  4 user4
  5 user5

どんな定義でロードされるの?

実行時の定義(コントロールファイルの内容)は、実行ログから確認できます。
今回の場合は、以下の定義でロードされています。
OPTIONS(EXTERNAL_TABLE=EXECUTE, TRIM=LRTRIM)
LOAD DATA
INFILE 'users'
APPEND
INTO TABLE USERS
FIELDS TERMINATED BY ","
(
  USER_ID,
  NAME CHAR(400)
)

デフォルト値の上書き方法

デフォルト値はコマンドラインパラメータで上書きします。例えば、フィールドの区切り文字をデフォルトのカンマ(,)から縦棒(|)に変更したい場合には以下のようにします。
sqlldr hoge/hoge@orcl TABLE=users TERMINATED_BY='|'

変更できる項目はマニュアルで参照できます。

2015年6月24日水曜日

SQL*Loaderでインプットファイルの論理行番号をテーブルに格納する

SQL*Loaderでデータロード時に、ファイルの論理レコード番号をテーブルに格納したい場合には、RECNUMパラメータを使用する。
RECNUMを使用するとスキップしたレコードや不良レコード、破棄レコードも1レコードとしてカウントされる。

ロード先のテーブル定義

名前       NULL?    型
--------- -------- ----------------------------
REC_NUM   NOT NULL NUMBER
NAME               VARCHAR2(100)

コントロールファイルの内容

論理行番号を格納したいカラムにRECNUMパラメータを使用する。
OPTIONS (SKIP=1)
LOAD DATA
CHARACTERSET 'AL32UTF8'
INFILE 'input.csv' "str '\n'"
BADFILE 'input.bad'
DISCARDFILE 'input.dsc'
TRUNCATE
INTO TABLE HOGE
FIELDS TERMINATED BY ',' 
(
REC_NUM RECNUM,
NAME OPTIONALLY ENCLOSED BY '"' 
)

CSVファイルの内容

タイトル行あり、不正なレコード(空行)ありのファイル。
name
あ
い

う
え
お

実行結果の確認

以下のコマンドで、上のCSVファイルを取り込みます。
sqlldr 接続先情報 control=input.ctl

スキップしたヘッダー行や不正なレコードの空行もレコード数としてカウントアップされているのが分かる。
1* select * from hoge

REC_NUM    NAME
---------- ------------------------------
2          あ
3          い
5          う
6          え
7          お

2015年6月12日金曜日

[PostgreSQL]単一のINSERT文で複数レコードを登録

INSERT文のVALUES区に登録対象のレコード情報をカンマ(,)区切りで複数列挙することで一括登録ができる

SQL例

使い方は簡単で、INSERTのVALUE句に設定する。
INSERT INTO users (id, name) VALUES
    (1, 'hoge'),
    (2, 'fuga')