30章 制約(後半)
では前回に引き続き制約のお話となります。
前回は制約とは?なぜ必要なのか、そして定義方法について学んできました。
今回は制約タイプの続きとなります。
・NOT NULL
・UNIQUE(一意制約)
・PRIMARY KEY(主キー)
・FOREIGN KEY(外部キー)
・CHECK
複合制約
前回は単一列を使用した実行例でしたが、複数列を組合わせて制約を定義することもできます。
SQL> CREATE TABLE emp3
2 ( id number(5),
3 name varchar2(30),
4 mail varchar2(30),
5 tel varchar2(10),
6 constraint emp2_id_pk primary key(id,name));
Table created.
上記例の場合は、id列とname列に主キー制約を定義しました。
この2つの列の組み合わせで、一意な値のみ挿入できます。
SQL> INSERT INTO emp3(id,name) VALUES (1,'A');
1 rows created.
SQL> INSERT INTO emp3(id,name) VALUES (1,'B');
1 rows created.
SQL> INSERT INTO emp3(id,name) VALUES (1,'A');
INSERT INTO emp3(id,name) VALUES (1,'A');
*
ERROR at line 1:
ORA-00001: unique constraint (ORA.EMP2_ID_PK) violated
上記例では、3つ目のINSERT文が1つ目のINSERT文と
id,name列が同じ値なため、エラーとなっています。
SQL> INSERT INTO emp3(id,name) values (1,NULL);
INSERT INTO emp3(id,name) values (1,NULL);
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("ORA"."EMP1"."ID")
上記例ではname列にNULLを挿入しようとしています。
複合索引の主キーでも同様、どちらかの列にNULLを挿入しようとするとエラーとなります。
外部キー制約
では次に外部キー制約について学んでいきましょう。
外部キー制約は少しイメージしづらい制約ですが、ゆっくり理解していきましょう。
外部キー制約は参照する列と同じ値しか挿入できないようにする制約です。
外部キーを定義する場合には参照する表の列名を指定する必要があります。
例えばEMPLOYEES表のDEPT_ID列を参照するDEPARTMENTS表の
DEPT_IDに外部キーを定義したとします。
上記では最初にINSERTしたDEPT_ID列の値は10です。
10は参照するDEPT_ID列に存在するため、INSERTは成功します。
次の値の20も存在するため、成功します。
次の値の70はDEPT_ID列には存在しない為、エラーとなります。
またNULL値は挿入可能である為、次のINSERT文は成功します。
それでは構文です。
[構文] 列レベル定義 テーブルの作成
CREATE TABLE 表名 (
列A データ型 ,
列B データ型 [ CONSTRAINT 制約名 ]
REFERENCES 参照する表(列名),
列C データ型)
[構文] 表レベル定義 テーブルの作成
CREATE TABLE 表名 (
列A データ型 ,
列B データ型 ,
列C データ型 ,
[ CONSTRAINT 制約名 ] FOREIGN KEY(列B)
REFERENCES 参照する表名(列名));
FOREIGN KEYの後ろに指定する列は外部キー制約を定義したい列名を指定します。
REFERENCESの後に指定するのは参照する表名と列名を指定します。
また外部キー制約で使用する参照列は主キー制約か一意制約である必要があります。
そうでない場合は定義するときにエラーが発生します。
今回の例では列レベル、表レベル両方とも列Bに対し、外部キー制約を定義しています。
外部キー制約は以上となります。
CHECK制約
最後にCHECK制約について学んでいきます。
CHECK制約はもっとも柔軟な制約で、自分で挿入する条件を設定することができます。
例えば、挿入する値は整数であるという場合は、
CHECK ( 列名 > 0 )
挿入する値がLから始まるという条件を定義したいのであれば、
CHECK ( 列名 LIKE 'L%' )
WHERE句で使用する条件式を使用して、制約を定義できるのがCHECK制約です。
これはもっとも柔軟ですね。実行例を見ていきましょう。
SQL> CREATE TABLE emp4
2 ( id number(5),
3 name varchar2(30) CONSTRAINT emp3_name_ck
4 CHECK ( name like 'L%'),
4 mail varchar2(30) ,
5 tel varchar2(10));
Table created.
SQL> INSERT INTO emp4(id,name,mail,tel)
2 VALUES (1,'Lon','AAA','090');
1 row created.
SQL> INSERT INTO emp4(id,name,mail,tel)
2 values (2,'Tom','BBB','080');
insert into emp4(id,name,mail,tel) values (2,'Tom','BBB','080')
*
ERROR at line 1:
ORA-02290: check constraint (ORA.EMP3_NAME_CK) violated
CHECK制約により大文字Lから始まる値しか挿入できないため、
Tomという値はエラーとなっています。
いかがでしたでしょうか。制約があるおかげで、挿入される値を
毎回チェックしなくてすむようになります。
以上が制約についてのご紹介となります。