Oracle のマルチテーブル・インサート

最近は PostgreSQL の機能も充実してきましたが Oracle にはまだまだ独自の機能が残っています。

今回は、前回やったマルチテーブル・インサートについて。

次のように INSERT文をまとめることができます。

SQL> INSERT ALL
  2    INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx')
  3    INTO table1 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx')
  4    INTO table1 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx')
  5  SELECT * FROM DUAL;

まとめるだけでなく複数のテーブルに INSERT できます。

SQL> INSERT ALL
  2    INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx')
  3    INTO table2 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx')
  4    INTO table3 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx')
  5  SELECT * FROM DUAL;

文末の DUAL に気づいたでしょうか?

  5  SELECT * FROM DUAL;

ここにはテーブルや福問い合わせを指定することができます。

つまり 次のようなことができてしまうわけです。

SQL> INSERT ALL
  2    INTO table1 (field1, field2) VALUES (fieldA, fieldB)
  3    INTO table2 (field1, field2) VALUES (fieldA, fieldC)
  4    INTO table3 (field1, field2) VALUES (fieldA, fieldD)
  5  SELECT * FROM table4;

さらに条件も指定することができます。

SQL> INSERT ALL
  2    WHEN fieldB < 10 THEN
  3      INTO table1 (field1, field2) VALUES (fieldA, fieldB)
  4    WHEN fieldC < 10 THEN
  5      INTO table2 (field1, field2) VALUES (fieldA, fieldC)
  6    WHEN fieldD < 10 THEN
  7      INTO table3 (field1, field2) VALUES (fieldA, fieldD)
  8  SELECT * FROM table4;

やっぱり Oracle は恐ろしいですね。

Oracle でも 1回の SQL で複数行 INSERT する

PostgreSQL や MySQL では次のように INSERT 文で 複数行を指定することができます。

psql=# INSERT INTO table1 (field1, field2)
psql-#   VALUES ('xxxxx1', 'xxxxxxxxx')
psql-#        , ('xxxxx2', 'xxxxxxxxx')
psql-#        , ('xxxxx3', 'xxxxxxxxx');

Oracle ではこの書き方ができません。

以下のように書きます。

SQL> INSERT ALL
  2    INTO table1 (field1, field2) VALUES ('xxxxx1', 'xxxxxxxxx')
  3    INTO table1 (field1, field2) VALUES ('xxxxx2', 'xxxxxxxxx')
  4    INTO table1 (field1, field2) VALUES ('xxxxx3', 'xxxxxxxxx')
  5  SELECT * FROM DUAL;

単に INSERT文をまとめただけのようですが この書き方は、異なるテーブルでもまとめることができます。 マルチテーブル・インサート と言うのですが 単に INSERT をまとめるだけではありません。

詳しくは次回。

Oracle で簡単棒グラフ表示

Oracle の SQL で簡単に棒グラフを作る小ネタです。

表示制御のために COLUMN とかを使っていますが ポイントは LPAD 関数の使い方です。

SQL> COLUMN TNAME FORMAT A30
SQL> COLUMN BAR   FORMAT A30

SQL> SELECT tname, LPAD('*', LENGTH(tname), '*') AS bar FROM TAB;

TNAME                          BAR
------------------------------ ------------------------------
W_AB_T_OPTAR_POLOLOPL_CLOSED   ****************************
W_START                        *******
E_AB_T_PLANT                   ************
E_AB_T_EERCC_BODY              *****************
E_AB_T_EERCC_HEAD              *****************
E_AB_PLANT_DATA                ***************
E_AB_KUJIDE_BODY               ****************
E_AB_KUJIDE_HEAD               ****************
R_AB_T_OPTAR_CLOSED            *******************
R_AB_T_OPTAR_KAMOKU            *******************
R_AB_KK_DATA                   ************

このサンプルはテーブルの名前の長さという かなりどうでも良いものを棒グラフにしてますが (棒グラフ化しなくてもそのままですし)、 棒グラフ化することで 見えやすくなるものは結構あると思います。