※当サイトの記事には、広告・プロモーションが含まれます。

CREATE TABLEでAS SELECTを使うといろいろ引き継がれない件

xtech.nikkei.com

COBOL卒業できるんですかね?

CREATE TABLEでAS SELECTを使うといろいろ引き継がれない件

困ったのが、公式のドキュメントに載ってなくて、「Oracle TimesTen In-Memory Database」っていうインメモリデータベースのドキュメントには、

docs.oracle.com

AS SelectQuery句を指定する場合:

  • 一意キー、外部キー、索引および列のデフォルト値は、新しい表に引き継がれません。

https://docs.oracle.com/cd/E16662_01/doc/timesten.1121/b56051/ttsql302.htm

⇧ って載ってるのだけど、Oracle Database 11gで、

CREATE TABLE [table_name] AS SELECT * FROM [table_name]

⇧ って感じで、テーブルを作成したら、元のテーブルに存在していたはずの「primary key(主キー)」や「foreign key(外部キー)」などの「constraint」で定義してたような制約が引き継がれないという...

「constraint」はと言うと、

docs.oracle.com

constraintを使用すると、整合性制約(データベース内の値を制限する規則)を定義できます。Oracle Databaseでは、6つの制約を作成し、それを2つの方法で宣言することができます。

https://docs.oracle.com/cd/E16338_01/server.112/b56299/clauses002.htm

次に、6つの整合性制約について簡単に説明します。詳細は、「セマンティクス」を参照してください。

  • NOT NULL制約は、データベースの値がNULLになることを禁止します。

  • 一意制約は、複数の行が同じ列または列の組合せで同じ値を持つことを禁止しますが、一部の値がNULLになることを許可します。

  • 主キー制約は、1つの宣言でNOT NULL制約と一意制約を組み合せたものです。これにより、同じ列または列の組合せで、複数の行の値が同じにならないように、また値がNULLにならないようにします。

  • 外部キー制約は、ある表の値が別の表の値と一致することを必要とします。

  • CHECK制約は、データベースの値が、指定された条件を満たすことを必要とします。

  • REF列は、定義上は別のオブジェクト型またはリレーショナル表の中のオブジェクトを参照します。REF制約を使用すると、REF列と参照先のオブジェクトの関係をさらに詳しく指定できます。

https://docs.oracle.com/cd/E16338_01/server.112/b56299/clauses002.htm

制約は、次の2つの構文で定義できます。

  • 個々の列または属性の定義の一部として定義できます。これを、表内指定といいます。

  • 表定義の一部として定義できます。これを、表外指定といいます。

NOT NULL制約は、表内に宣言する必要があります。その他のすべての制約は、表内または表外に宣言できます。

https://docs.oracle.com/cd/E16338_01/server.112/b56299/clauses002.htm

⇧ のような感じの説明になってますと。

ネット上の情報によりますと、

www.shift-the-oracle.com

CREATE TABLE AS SELECT を使用するとテーブルの定義とデータの複製を同時に行なうことができる。
但し、プライマリキーやインデックスなどは複製されない。

テーブル定義 - オラクル・Oracle SQL 入門

⇧ 上記サイト様が、制約が引き継がれないって話を記載してくださっているのですが、参照した一次情報については不明ですと...

う~む、公式のドキュメントに記載が無いってのが一番困るんだが、自分の試した環境(Oracle Database 11g)では、少なくとも、

  • primary key(主キー)
  • foreign key(外部キー)

は引き継がれることが無かったので、「constraint」で定義してた制約は引き継がれないのではないか説があるんだけど、公式のドキュメントで『CREATE TABLE AS SELECT文で引き継がれない内容について』の記載が見つけられないので憶測の域を出ない推測になってしまうので困ったものです...

ちなみに、ChatGPTに確認してみましたが、全く役に立ちませんでした...

まぁ、Oracleさんがしれっとドキュメントを無かったことにして更新するのも影響してるとは思うけども…

というわけで、相変わらず安定の不親切さを発揮するOracleさん。

結局のところ、

CREATE TABLE [table_name] AS SELECT * FROM [table_name]

で引き継がれない情報については、よく分かりませんでした...

Oracleさんがドキュメントを整備してくれるような気もしないし...本当に困ったもんだ...

ちなみに、19cのドキュメントだと、

docs.oracle.com

  • CREATE TABLE AS SELECTを使用すると、列に対するIDのプロパティが継承されなくなります。

https://docs.oracle.com/cd/F19136_01/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6

⇧ としか記載がないので、19cだと「constraint」で定義してた制約とかも全て引き継がれるんですかね?

まぁ、IDのプロパティが具体的に何を示してるのかがサッパリ分からんので何とも言えんけど...

毎度モヤモヤ感が半端ない...

今回はこのへんで。