既存のテーブルの構造も中のデータもまるごとコピーして、名前だけ違うテーブルを作りたい。
というとき、Create Table as Select文が便利です。
しかし標準のSQLではないということなのか、RDBごとに構文が異なります。
(といっても2種類しか確認できていませんが)
【Oracle 23ai の場合】
SQL> create table A as select * from T1;
Table created.
SQL>
【Db2 12.1 の場合】
データの複製を行うか(WITH DATA)、テーブル定義のみコピーするか(WITH NO DATA)を指定するオプションが必要。
さらに、as select部分をカッコで囲まないと構文エラーとなります。
$ db2 "create table A as (select * from T1) with data"
DB20000I SQL コマンドが正常に完了しました。
これで、上のOracle 23aiと同じくデータごと表をコピーできました。
補足(1)エラー例
Db2でOracleと同じ構文でCTAS実行するとこうなる、という例。
1) WITH DATA または WITH NO DATA オプション欠落
$ db2 "create table a as select * from t1"
DB21034E コマンドが、有効なコマンド行プロセッサー・コマ
ンドでないため、 SQL
ステートメントとして処理されました。 SQL
処理中に、次のエラーが返されました。
SQL0104N "as select * from T1" に続いて予期しないトークン
"END-OF-STATEMENT" が見つかりました。 予期されたトークンに
"WITH DATA, WITH NO DATA" が含まれている可能性があります。
SQLSTATE=42601
WITH DATA, WITH NO DATA どちらかがデフォルトで選択されるわけでない点は、良心的なのかもしれないです。
2) カッコ指定忘れ
$ db2 "create table a as select * from t1 with data"
DB21034E コマンドが、有効なコマンド行プロセッサー・コマ
ンドでないため、 SQL
ステートメントとして処理されました。 SQL
処理中に、次のエラーが返されました。
SQL0104N "elect * from t1 with" に続いて予期しないトークン "data"
が見つかりました。 予期されたトークンに "END-OF-STATEMENT"
が含まれている可能性があります。 SQLSTATE=42601
補足(2)オンラインで表をコピーする方法?
Db2ではオンラインで更新がかかっている状態のテーブルを別の表スペースに移動したいとき、ADMIN_MOVE_TABLEプロシージャーが使えます。
元表を別名で残して置けるオプション(KEEP)もあるため、表の複製にも使えそうではあります。
ただし、コピー先が別の表スペースとなります。
統計情報も一緒にコピーできるなど単純な表移動、コピー以上のことをしてくれますが元表の名前は維持されず、別の表名に変更されてしまいます。このためrenameコマンドでターゲット表をリネームし、Db2に自動名称変更されてしまった元表を元の名前に戻し、という手間が生じます。
単純に表をコピーしたいだけならCTASのほうがシンプルだと思いました。