用途
constraint
を使用すると、整合性制約(データベース内の値を制限する規則)を定義できます。Oracle Databaseでは、6つの制約を作成し、それを2つの方法で宣言することができます。
次に、6つの整合性制約について簡単に説明します。詳細は、「セマンティクス」を参照してください。
NOT
NULL
制約は、データベースの値がNULLになることを禁止します。
一意制約は、複数の行が同じ列または列の組合せで同じ値を持つことを禁止しますが、一部の値がNULLになることを許可します。
主キー制約は、1つの宣言でNOT
NULL
制約と一意制約を組み合せたものです。これにより、同じ列または列の組合せで、複数の行の値が同じにならないように、また値がNULLにならないようにします。
外部キー制約は、ある表の値が別の表の値と一致することを必要とします。
CHECK制約は、データベースの値が、指定された条件を満たすことを必要とします。
REF
列は、定義上は別のオブジェクト型またはリレーショナル表の中のオブジェクトを参照します。REF制約を使用すると、REF
列と参照先のオブジェクトの関係をさらに詳しく指定できます。
制約は、次の2つの構文で定義できます。
個々の列または属性の定義の一部として定義できます。これを、表内指定といいます。
表定義の一部として定義できます。これを、表外指定といいます。
NOT
NULL
制約は、表内に宣言する必要があります。その他のすべての制約は、表内または表外に宣言できます。
制約句は、次の文に指定できます。
CREATE
TABLE
(「CREATE TABLE」を参照)
ALTER
TABLE
(「ALTER TABLE」を参照)
CREATE
VIEW
(「CREATE VIEW」を参照)
ALTER
VIEW
(「ALTER VIEW」を参照)
ビュー制約 Oracle Databaseでは、ビュー制約を適用していません。ただし、実表に対する制約によってビューに制約を適用できます。
ビューには、一意制約、主キー制約および外部キー制約のみを指定でき、これらの制約はDISABLE
NOVALIDATE
モードのみでサポートされています。オブジェクト列の属性にビュー制約を定義することはできません。
前提条件
制約を定義する文を発行できる権限が必要です。
外部キー制約を作成する場合は、この条件に加えて、親表またはビューが自分のスキーマ内に設定されている必要があります。設定されていないかぎり、親表またはビューの参照キー列に対するREFERENCES
権限が必要です。
構文
constraint::=
(inline_constraint::=、out_of_line_constraint::=、inline_ref_constraint::=、out_of_line_ref_constraint::=を参照)
inline_constraint::=
(references_clause::=を参照)
out_of_line_constraint::=
(references_clause::=、constraint_state::=を参照)
inline_ref_constraint::=
(references_clause::=、constraint_state::=を参照)
out_of_line_ref_constraint::=
(references_clause::=、constraint_state::=を参照)
(using_index_clause::=、exceptions_clause::=を参照)
(create_index::=、index_properties::=を参照)
index_properties::=
(global_partitioned_index::=、local_partitioned_index ::=(「CREATE
INDEX
」の項)、index_attributes::=を参照。INDEXTYPE
IS
...句は、制約を定義すると無効になります。)
index_attributes::=
(physical_attributes_clause::=, logging_clause::=, index_compression::=, partial_index_clause::=「CREATE
INDEX
」の項の「parallel_clause
」をすべて参照。using_index_clause
ではサポートされません。)
セマンティクス
この項では、constraint
のセマンティクスについて説明します。詳細は、表またはビューの制約を定義または再定義するSQL文の説明を参照してください。
Oracle Databaseでは、ユーザー定義オブジェクト、ネストした表、VARRAY
、REF
またはLOB型の列または属性に対して制約を使用することはできません。ただし、次の2つの例外があります。
NOT
NULL
制約は、ユーザー定義オブジェクト、VARRAY
、REF
またはLOB型の列や属性に使用できます。
NOT
NULL
、外部キーおよびREF
制約は、REF
型の列に使用できます。
CONSTRAINT constraint_name 制約名を指定します。この識別子を指定しない場合、SYS_C
n
の形式で名前が生成されます。整合性制約の名前と定義は、USER_
、ALL_
およびDBA_CONSTRAINTS
データ・ディクショナリ・ビュー(それぞれCONSTRAINT_NAME
列およびSEARCH_CONDITION
列)に格納されます。
関連項目: データ・ディクショナリ・ビューの詳細は、『Oracle Databaseリファレンス』を参照してください。 |
NOT NULL制約
NOT
NULL
制約は、列にNULLが含まれることを禁止します。NULL
キーワード自体は、実際に整合性制約を定義するものではありませんが、これを指定すると、列にNULLが含まれることが許可されます。NOT
NULL
およびNULL
は、表内指定で定義する必要があります。NOT
NULL
またはNULL
を指定しない場合、NULL
がデフォルトになります。
NOT
NULL
制約は、XMLType
列およびVARRAY
列で表内指定できる唯一の制約です。
NOT
NULL
制約を満たすには、表のすべての行がその列の値を持つ必要があります。
注意: Oracle Databaseでは、すべてのキー列がNULLの表の行には索引を付けません(ただし、ビットマップ索引の場合を除きます)。このため、表のすべての行に索引を付けるには、1つ以上の索引キー列にNOT NULL 制約を指定するか、ビットマップ索引を作成する必要があります。 |
NOT NULL制約の制限事項: NOT
NULL
制約には次の制限事項があります。
ビュー制約にはNULL
またはNOT
NULL
を指定できません。
オブジェクト属性にはNULL
またはNOT
NULL
を指定できません。そのかわりに、IS
[NOT
] NULL
条件でCHECK
制約を使用してください。
一意制約
一意制約は、列を一意キーとして指定します。複合一意キーは、列の組合せを一意キーとして指定します。一意制約を表内に定義する場合に必要となるのは、UNIQUE
キーワードのみです。一意制約を表外に定義する場合は、1つ以上の列も指定する必要があります。複合一意キーは、表外に定義する必要があります。
一意制約を満たすには、表の中の2つの行が一意キーに対して同じ値を持たないようにする必要があります。ただし、単一の列で構成される一意キーの場合は、複数のNULLを持つことができます。複合一意キーを満たすには、表またはビューの2つの行がキー列に対して同じ組合せの値を持たないようにする必要があります。すべてのキー列に対してNULLを持つ行は、自動的にその制約を満たすことになります。ただし、1つ以上のキー列に対してNULLを持ち、その他のキー列に対して同じ組合せの値を持つ2つの行は、制約に違反します。
Oracleでは、1つ以上の列に一意制約を指定すると、暗黙的に一意キーに索引が作成されます。問合せのパフォーマンスを目的に一意性を定義する場合は、かわりにCREATE
UNIQUE
INDEX
文を使用して明示的に一意索引を作成することをお薦めします。また、CREATE
UNIQUE
INDEX
文で、条件付きの一意制約を定義する一意のファンクション索引を作成することもできます。詳細は、「ファンクション索引の使用による条件付き一意性の定義例:」を参照してください。
使用可能な一意制約を拡張データ型の列に指定すると、Oracleがその使用可能な制約の一意性を適用するための索引を作成しようとしたときに、「最大キー長を超過しました」というエラーが通知されることがあります。この問題を回避する方法の詳細は、「拡張データ型の列に対する索引の作成」を参照してください。
一意制約の制限事項: 一意制約には、次の制限事項があります。
一意キー列は、LOB、LONG
、LONG
RAW
、VARRAY
、NESTED
TABLE
、OBJECT
、REF
、TIMESTAMP
WITH
TIME
ZONE
またはユーザー定義型を含むことができません。ただし、一意キーはTIMESTAMP
WITH
LOCAL
TIME
ZONE
の列を含むことができます。
1つの複合一意キーは、33以上の列を持つことはできません。
同一の列または列の組合せを一意キーと主キーの両方には指定できません。
継承階層でサブビューを作成する場合は、一意キーを指定できません。一意キーは、トップレベル(ルート)のビューのみに指定できます。
主キー制約は、列を表またはビューの主キーとして指定します。複合主キーは、列の組合せを主キーとして指定します。主キー制約を表内に定義する場合に必要となるのは、PRIMARY
KEY
キーワードのみです。主キー制約を表外に定義する場合は、1つ以上の列も指定する必要があります。複合主キーは表外に定義する必要があります。
主キー制約を満たすには次の条件があります。
主キーの値が、表の中の複数行に存在することはできません。
主キーを構成する列に、NULLを持たせることはできません。
主キー制約を作成する場合
Oracle Databaseでは、主キー制約を適用する前に既存の索引に一意の値の集合が含まれる場合、その索引が使用されます。既存の索引は、一意であると定義されている場合も、一意でないと定義されている場合もあります。DML操作を実行すると、この既存の索引を使用して主キー制約が適用されます。
既存の索引を使用できない場合は、一意索引が生成されます。
主キー制約を削除する場合
既存の索引を使用して主キーが作成された場合、索引は削除されません。
システム生成の索引を使用して主キーが作成された場合、索引は削除されます。
拡張データ型の列を使用可能な主キーとして指定すると、Oracleがその使用可能な制約の一意性を適用するための索引を作成しようとしたときに「最大キー長を超過しました」というエラーが通知されることがあります。この問題を回避する方法の詳細は、「拡張データ型の列に対する索引の作成」を参照してください。
主キー制約の制限事項: 主キー制約には、次の制限事項があります。
表またはビューには、主キーを1つのみ指定できます。
主キー列は、LOB、LONG
、LONG
RAW
、VARRAY
、NESTED
TABLE
、BFILE
、REF
、TIMESTAMP
WITH
TIME
ZONE
またはユーザー定義型を含むことができません。ただし、主キーはTIMESTAMP
WITH
LOCAL
TIME
ZONE
の列を含むことができます。
主キーのサイズは、1データベース・ブロックを超えることはできません。
1つの複合主キーは、33以上の列を持つことはできません。
同一の列または列の組合せを一意キーと主キーの両方には指定できません。
継承階層でサブビューを作成する場合は、主キーを指定できません。主キーは、トップレベル(ルート)のビューのみに指定できます。
外部キー制約(参照整合性制約ともいう)は、列を外部キーとして指定し、その外部キーと指定した主キーまたは一意キー(参照キー)との関係を設定します。複合外部キーは、列の組合せを外部キーとして指定します。
外部キーを持つ表またはビューを子オブジェクトといい、参照キーを持つ表またはビューを親オブジェクトといいます。外部キーと参照キーを、同一の表またはビューに設定することができます。この場合、親表と子表は同一の表になります。親表または親ビューのみを指定して、列名を指定しない場合、外部キーは自動的に親表または親ビューの主キーを参照します。外部キーと参照キーの対応する列は、同じ順序とデータ型で構成されている必要があります。
単一キー列の外部キー制約は、表内または表外に定義できます。複合外部キーと属性の外部キーは、表外に指定します。
複合外部キー制約を満たすには、複合外部キーが親表または親ビューの複合一意キーまたは複合主キーを参照するか、外部キーの1つ以上の列の値がNULLである必要があります。
外部キーと主キーの両方、または外部キーと一意キーの両方に、同一の列または列の組合せを指定できます。また、外部キーとクラスタ・キーの両方にも同じ列または列の組合せを指定できます。
1つの表またはビューで複数の外部キーを定義できます。また、1つの列が複数の外部キーを構成することもできます。
外部キー制約の制限事項: 外部キー制約には、次の制限事項があります。
外部キー列は、LOB、LONG
、LONG
RAW
、VARRAY
、NESTED
TABLE
、BFILE
、REF
、TIMESTAMP
WITH
TIME
ZONE
またはユーザー定義型を含むことができません。ただし、主キーはTIMESTAMP
WITH
LOCAL
TIME
ZONE
の列を含むことができます。
親表または親ビューの参照一意制約または参照主キー制約が事前に定義されている必要があります。
1つの複合外部キーは、33以上の列を持つことはできません。
子表と親表は、同一データベース上に設定されている必要があります。分散データベースのノード間の参照整合性制約を使用可能にする場合、データベース・トリガーを使用する必要があります。「CREATE TRIGGER」を参照してください。
子オブジェクトと親オブジェクトのどちらかがビューの場合、ビュー制約のすべての制限事項が制約に適用されます。「ビュー制約」を参照してください。
AS
subquery
句を含むCREATE
TABLE
文には、外部キー制約を定義できません。そのかわりに、制約を指定せずに表を作成し、後でALTER
TABLE
文を使用してその制約を追加できます。
表に外部キーがあり、外部キーの親が索引構成表である場合、他のセッションが親表の非キー列を更新している場合、外部キーを含む行を更新するセッションはハングします。
references_clause 外部キー制約はreferences_clause
構文を使用します。外部キー制約を表内に指定する場合に必要となるのは、references_clause
のみです。外部キー制約を表外に指定する場合は、FOREIGN
KEY
キーワードと1つ以上の列も指定する必要があります。
ON DELETE句 ON
DELETE
句を指定すると、参照主キーまたは参照一意キーの値を削除した場合に参照整合性がどのように自動処理されるかを指定できます。この句を指定しない場合、子表に依存する行を持つ親表の中の参照キーの値は削除できません。
依存する外部キーの値を削除する場合は、CASCADE
を指定します。
依存する外部キーの値をNULL
に変換する場合は、SET
NULL
を指定します。仮想列の値は直接更新できないため、仮想列に対してこの句を指定することはできません。仮想列が導出される値を更新する必要があります。
ON DELETEの制限事項: この句は、ビュー制約に対して指定できません。
CHECK制約によって、表の各行に必要な条件を指定できます。制約を満たすためには、表のそれぞれの行が、その条件に対してTRUE
または不明(NULLのため)のいずれかである必要があります。特定の行に対するCHECK制約条件が評価される場合、条件にある列名に、その行の列値が適用されます。
CHECK制約の表内指定と表外指定の構文は同じです。ただし、表内指定では現在定義されている列(または、オブジェクト列の場合は列の属性)のみを参照でき、表外指定では複数の列または属性を参照できます。
Oracleでは、CHECK制約の条件が相互に排他的かどうかは検証しません。このため、1つの列に対して複数のCHECK制約を作成する場合は、制約の用途が矛盾しないように注意する必要があります。また、条件の評価について特別な順序を想定しないでください。
CHECK制約の制限事項: CHECK制約には、次の制限事項があります。
ビューに対しては、CHECK制約を指定できません。ただし、WITH
CHECK
OPTION
句を使用してビューを定義することは可能です。これは、ビューにCHECK制約を指定することと同じです。
CHECK制約の条件では、その表の中のすべての列を参照できますが、他の表の列は参照できません。
CHECK制約の条件は、次の構造を持つことができません。
副問合せおよびスカラー副問合せ式
決定的でないファンクションへのコール(CURRENT_DATE
、CURRENT_TIMESTAMP
、DBTIMEZONE
、LOCALTIMESTAMP
、SESSIONTIMEZONE
、SYSDATE
、SYSTIMESTAMP
、UID
、USER
およびUSERENV
)
ユーザー定義ファンクションへのコール
REF
列の参照解除(DEREF
ファンクションを使用する場合など)
ネストした表の列または属性
疑似列CURRVAL
、NEXTVAL
、LEVEL
またはROWNUM
完全に指定されていない日付定数
REF
制約を使用すると、REF
型の列とそれが参照するオブジェクトとの関係を指定できます。
ref_constraint REF
制約は、ref_constraint
構文を使用します。REF
制約は表内または表外に定義します。表外指定の場合は、指定しているREF
列または属性を指定する必要があります。
ref_column
には、オブジェクトまたはリレーショナル表のREF
列の名前を指定します。
ref_attribute
には、リレーショナル表のオブジェクト列内の埋込みREF
属性を指定します。
表内指定と表外指定のどちらでも、有効範囲制約、ROWID制約または参照整合性制約をREF
列に定義できます。
REF
列の有効範囲表または参照表が、主キーに基づくオブジェクト識別子を持っている場合、そのREF
列はユーザー定義REF
列です。
REF列のSCOPE制約
表がREF
列を持つ場合は、この列のそれぞれのREF
値が別のオブジェクト表内の行を参照する場合があります。SCOPE
句は、参照の有効範囲を1つの表scope_table
に制限します。REF
列または属性の値はscope_table
内のオブジェクトを指し、その場所にREF
列と同じ型のオブジェクト・インスタンスが格納されます。
REF
列内の参照の有効範囲を1つの表に制限する場合に、SCOPE
句を指定します。この句を指定するには、scope_table
が自分のスキーマ内にあるか、またはscope_table
に対するREAD
またはSELECT
権限あるいはREAD
ANY
TABLE
またはSELECT
ANY
TABLE
システム権限が必要です。REF
列ごとに有効範囲表を1つのみ指定できます。
有効範囲制約の制限事項: 有効範囲制約には、次の制限事項があります。
表が空でない場合は、有効範囲制約を既存の列に追加できません。
VARRAY
列のREF
要素に対しては有効範囲制約を指定できません。
AS
subquery
を指定し、この副問合せがユーザー定義REF
データ型を戻す場合、この句を指定する必要があります。
有効範囲制約を、後でREF
列から削除することはできません。
WITH
ROWID
を指定して、ref_column
またはref_attribute
のREF
の値とともにROWIDを格納します。ROWIDとともにREF
値を格納した場合、参照解除操作のパフォーマンスは向上しますが、使用する領域も多くなります。デフォルトのREF
値の記憶域では、ROWIDは格納されません。
ROWID制約の制限事項: ROWID制約には、次の制限事項があります。
VARRAY
列のREF
要素に対してはROWID制約を定義できません。
ROWID制約を、後でREF
列から削除することはできません。
REF
列または属性の範囲が限定される場合、この句は無視され、ROWIDはREF
とともには格納されません。
REF列の参照整合性制約
ref_constraint
構文のreferences_clause
を使用すると、外部キー制約をREF
列に定義できます。また、この句はREF
列や属性の有効範囲を参照表に暗黙的に制限します。ただし、REF
列以外の外部キー制約が親表の実際の列を参照することに対し、REF
列の外部キー制約は親表の暗黙のオブジェクト識別子を参照します。
制約名を指定しない場合、制約に対するシステム名が
SYS_C
n
という形式で生成されます。
範囲が限定されている既存のREF
列に参照整合性制約を追加する場合、参照表は、REF
列の有効範囲表と同じである必要があります。後で参照整合性制約を削除する場合、REF
列の範囲が参照表に限定されたままになります。
他の型の列に対する外部キー制約と同様に、表内で宣言する場合に必要となるのはreferences_clause
のみです。表外で宣言する場合は、FOREIGN
KEY
キーワード、および1つ以上のREF
列または属性も指定する必要があります。
関連項目: オブジェクト識別子の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。 |
REF列の外部キー制約の制限事項: REF
列における外部キー制約には、次の追加の制限事項があります。
範囲が限定されていない既存のREF
列に参照整合性制約を追加する場合、有効範囲制約が暗黙的に追加されます。したがって、有効範囲制約に適用されるすべての制限事項は、この場合にも適用されます。
references_clause
内のオブジェクト名の後には列を指定できません。
制約状態の指定
制約定義の一部として、制約が適用される方法およびタイミングを指定できます。
constraint_state constraint_state
は、表内指定と表外指定の両方に使用できます。constraint_state
の句を表示される順序(上から下)で指定します。いずれの句も複数回は指定できません。
DEFERRABLE句 DEFERRABLE
およびNOT
DEFERRABLE
パラメータは、後続のトランザクションで、SET
CONSTRAINT
(S
)文を使用して、トランザクションが終わるまで制約のチェックを遅延できるかどうかを指定します。この句を指定しない場合、NOT
DEFERRABLE
がデフォルトになります。
NOT
DEFERRABLE
を指定すると、後続のトランザクションで、SET
CONSTRAINT
[S
]句を使用して、トランザクションがコミットされるまでこの制約のチェックを遅延させることができません。NOT
DEFERRABLE
制約のチェックは、トランザクションの終わりまで遅延させることはできません。
新しいNOT
DEFERRABLE
制約を宣言する場合、CREATE
TABLE
またはALTER
TABLE
文のコミット時にその制約が有効である必要があります。有効でない場合、これらの文は正常に実行されません。
DEFERRABLE
を指定すると、後続のトランザクションで、SET
CONSTRAINT
[S
]句を使用して、COMMIT
文が発行されるまでこの制約のチェックを遅延させることができます。制約のチェックに失敗した場合、エラーが戻され、トランザクションはコミットされません。この設定によって、制約に違反する可能性のある変更をデータベースに行っている場合に、すべての変更が完了するまで、制約を一時的に使用禁止にすることが可能になります。
注意: オプティマイザは遅延可能制約の索引を使用可能として考慮しません。 |
制約の遅延可能状態は変更できません。これらのパラメータのいずれを指定するか、どちらも指定せずにNOT
DEFERRABLE
制約を暗黙的に有効にするかに関係なく、この句をALTER
TABLE
文に指定することはできません。制約を削除してから再作成する必要があります。
関連項目:
|
[NOT] DEFERRABLEの制限事項: ビュー制約にはこれらのパラメータを指定できません。
INITIALLY句 INITIALLY
句は、DEFERRABLE
句が指定されている制約に対するデフォルトのチェック動作を指定します。INITIALLY
設定は、後続のトランザクションにSET
CONSTRAINT
(S
)文を指定することで上書きできます。
INITIALLY
IMMEDIATE
を指定すると、この制約は後続の各SQL文の終わりでチェックされます。INITIALLY
を指定しない場合、INITIALLY
IMMEDIATE
がデフォルトになります。
新しいINITIALLY
IMMEDIATE
制約を宣言する場合、CREATE
TABLE
またはALTER
TABLE
文のコミット時にその制約が有効である必要があります。有効でない場合、これらの文は正常に実行されません。
制約をNOT
DEFERRABLE
として宣言した場合、この句は無効です。NOT
DEFERRABLE
制約は自動的にINITIALLY
IMMEDIATE
になり、INITIALLY
DEFERRED
に変更することはできないためです。
VALIDATE | NOVALIDATE VALIDATE
およびNOVALIDATE
の動作は、制約が明示的にまたはデフォルトで使用可能/使用禁止のどちらになっているかで異なります。VALIDATE
およびNOVALIDATE
キーワードは、「ENABLE句」および「DISABLE句」で説明されています。
NOVALIDATEモードでの外部キー制約の注意事項 外部キー制約がNOVALIDATE
モードの場合、表内の既存のデータが制約に準拠せず、QUERY_REWRITE_INTEGRITY
パラメータがENFORCED
に設定されていないと、オプティマイザが表の問合せ時に結合の絞込みを使用することがあります。この場合、準拠しない外部キー値を持つ表の行をフィルタで除外する結合条件が問合せに含まれている場合でも、問合せはこのような行を返すことがあります。
ENABLE句 表のデータに制約を適用するには、ENABLE
を指定します。
一意制約または主キー制約を使用可能にした場合、キーに索引が存在しないと、一意索引が作成されます。KEEP INDEX
を指定しないかぎり、その後で制約が使用禁止になった場合にこの索引は削除されます。そのため、制約が使用可能になるたびに索引が再作成されます。
索引の再作成を避け、余分な索引を削除するには、最初に使用禁止にした主キー制約および一意制約を新しく作成します。その後、一意でない索引を作成して(または、既存の一意でない索引を使用して)制約を適用してください。制約が使用禁止の場合、一意でない索引は削除されず、後続のENABLE
操作が容易になります。
ENABLE
VALIDATE
を使用すると、すべての旧データと新データが制約に従うことを指定できます。制約が使用可能で、妥当性チェック済の場合は、すべてのデータが現在有効で、今後も有効であることが保証されます。
整合性制約に違反する行が表にある場合、制約は使用禁止のままエラーを戻します。すべての行が制約に従っている場合、Oracleは制約を使用可能にします。新規データが整合性制約に違反する場合、その後の文は実行されず、整合性制約の違反を示すエラーが戻されます。
主キー制約をENABLE
VALIDATE
モードに設定すると、妥当性チェック・プロセスによって主キー列にNULLが含まれないことが検証されます。これによるオーバーヘッドを回避するには、データを列に入力する前およびこの表の主キー制約を使用可能にする前に、主キーの各列にNOT
NULL
のマークを付けます。
ENABLE
NOVALIDATE
を使用すると、制約データに対して新しく行うすべてのDML操作が制約に従うことが保証されます。表の既存データが制約に従っていることは保証されません。
VALIDATE
もNOVALIDATE
も指定しない場合、VALIDATE
がデフォルトになります。
ENABLE
NOVALIDATE
からENABLE
VALIDATE
に単一制約状態を変更すると、パラレルで操作が実行できるため、読込み、書込みまたはその他のDDL操作が中断されません。
ENABLE句の制限事項: 使用禁止になっている一意キーまたは主キーを参照する外部キーを使用可能にすることはできません。
DISABLE句 整合性制約を使用禁止にする場合は、DISABLE
を指定します。データ・ディクショナリでは、使用禁止になっている整合性制約は、使用可能な制約とともに表示されます。この句を指定せずに制約を作成した場合は、その制約は自動的に使用可能になります。
DISABLE
VALIDATE
は、制約を使用禁止にして制約の索引を削除しますが、制約は有効のままです。この機能を使用すると、大量のデータをロードでき、また索引用の領域が削減されるため、データ・ウェアハウスで非常に有効です。この設定を使用することで、ALTER
TABLE
文のexchange_partition_subpart
句またはSQL*Loaderを使用して、データを非パーティション表からパーティション表にロードすることもできます。他のSQL文を使用した表に対するすべての変更(挿入、更新および削除)は禁止されます。
関連項目: この設定の使用方法の詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。 |
DISABLE
NOVALIDATE
は、Oracleによって制約がメンテナンスされないこと(使用禁止になっているため)、および制約が真であると保証されないこと(妥当性チェックが行われていないため)を示します。
外部キー制約がDISABLE
NOVALIDATE
状態であっても、外部キーが参照している主キーを持つ表を削除できません。また、オプティマイザは、DISABLE
NOVALIDATE
状態でも制約を使用できます。
関連項目: この設定を使用する状況の詳細は、『Oracle Database SQLチューニング・ガイド』を参照してください。 |
VALIDATE
もNOVALIDATE
も指定しない場合、NOVALIDATE
がデフォルトになります。
一意索引を使用している一意制約または主キー制約を使用禁止にすると、一意索引は削除されます。その他の注意事項や制限事項は、「CREATE
TABLE
」の「enable_disable_clause」を参照してください。
RELY句 RELY
およびNORELY
パラメータは、NOVALIDATE
モードの制約をクエリー・リライトに対して考慮するかどうかを指定します。RELY
を指定すると、適用されていないクエリー・リライトに対するNOVALIDATE
モードの制約は、アクティブになります。その制約はNOVALIDATE
モードであるため、適用されません。デフォルト値はNORELY
です。
適用されない制約は、通常、マテリアライズド・ビューおよびクエリー・リライトにのみ有効です。QUERY_REWRITE_INTEGRITY
モードに従って、クエリー・リライトは、VALIDATE
モードの制約、またはRELY
パラメータが設定されたNOVALIDATE
モードの制約を使用して、結合情報を確認します。
RELY句の制限事項: RELY
には、遅延不可のNOT
NULL
制約を設定できません。
関連項目: マテリアライズド・ビューおよびクエリー・リライトの詳細は、『Oracle Databaseデータ・ウェアハウス・ガイド』を参照してください。 |
一意制約または主キー制約の状態を定義する場合は、制約の適用に使用する索引を指定すること、または制約の適用に使用する索引をOracleで自動作成することが可能です。
using_index_clause using_index_clause
は、一意制約または主キー制約を使用可能にしている場合にのみ指定できます。using_index_clause
の句はどのような順序でも指定できますが、各句を指定できるのは1回のみです。
schema
.index
を指定すると、指定した索引を使用して制約が適用されます。索引がない、または制約の適用に索引が使用できない場合、エラーが戻されます。
create_index_statement
を指定すると、索引が作成され、制約の適用に使用されます。索引が作成できない、または制約の適用に索引が使用できない場合、エラーが戻されます。
既存の索引の指定も、新しい索引の作成も行わない場合は、索引が自動で作成されます。この場合、次のようになります。
索引には制約と同じ名前が割り当てられます。
表がパーティション化されている場合、一意制約または主キー制約にローカル・パーティション索引またはグローバル・パーティション索引を指定できます。
using_index_clauseの制限事項: using_index_clause
には、次の制限事項があります。
この句は、ビュー制約に対して指定できません。
この句は、NOT
NULL
、外部キーまたはCHECK制約には指定できません。
索引構成表の主キーが使用可能な場合は、索引の指定(schema.index
)および作成(create_index_statement
)はできません。
index_attributes
のparallel_clause
は指定できません。
index_properties
のINDEXTYPE
IS
...句は、制約の定義では無効です。
関連項目:
|
制約の例外の処理
制約の状態を定義する場合は、制約に違反するすべての行のROWIDを格納する表を指定できます。
exceptions_clause exceptions_clause
構文を使用すると、例外の処理を定義できます。schema
を指定しない場合、自分のスキーマ内に例外表があるとみなされます。この句自体を指定しない場合、表の名前はEXCEPTIONS
になります。EXCEPTIONS
表または指定した表は、ローカル・データベースに存在する必要があります。
次のいずれかのスクリプトを使用して、EXCEPTIONS
表を作成できます。
UTLEXCPT.SQL
は、物理ROWIDを使用します。そのため、行は、索引構成表からではなく従来表から収集されます。(次の注意を参照。)
UTLEXPT1.SQL
は、ユニバーサルROWIDを使用します。そのため、行は、従来表と索引構成表の両方から収集されます。
独自の例外表を作成する場合、これら2つのスクリプトのいずれかで規定される形式に従う必要があります。
ユニバーサルROWIDではなく、主キーに基づく索引構成表から例外を収集する場合、索引構成表ごとに別の例外表を作成し、主キー記憶域を確保する必要があります。スクリプトを変更および再発行することによって、別の名前の例外表を複数作成できます。
exceptions_clauseの制限事項: exceptions_clause
には、次の制限事項があります。
この句は、ビュー制約に対して指定できません。
この文が正常に終了されるまでROWIDは存在しないため、この句をCREATE
TABLE
文に指定することはできません。
関連項目:
|
データ・ウェアハウスのアプリケーションは、リレーショナル・スキーマ内の参照整合性制約を識別することによって、Oracle Database内の多次元データを認識します。これらの制約によって、表間の主キーと外部キーの関係が表されます。Oracle Databaseデータ・ディクショナリを問い合せることによって、アプリケーションはそのような制約を認識できるようになるため、データベース内の多次元データを認識できます。スキーマの複雑さまたはセキュリティ上の理由のため、ファクト表およびディメンション表にビューを定義する必要がある場合があります。Oracle Databaseには、これらのビューを制約する機能があります。ビュー間で制約を定義できるようにすることによって、実表制約をビューに伝播できます。これによって、ビューで提供される制限された環境でも、アプリケーションで多次元データを認識できるようにすることができます。
Oracleでは、ビュー制約を適用していません。ただし、ビューに対する操作には、基となる実表に定義されている整合性制約が適用されます。つまり、実表に対する制約によって、ビューに制約を適用できます。
ビュー制約の注意事項: ビュー制約は表制約のサブセットで、次の制限事項があります。
ビューには、一意制約、主キー制約および外部キー制約のみ指定できます。ただし、WITH
CHECK
OPTION
句を使用してビューを定義することは可能です。これは、ビューにCHECK制約を指定することと同じです。
ビュー制約は、DISABLE
NOVALIDATE
モードのみでサポートされています。他のモードは指定できません。ビュー制約を宣言する場合は、キーワードDISABLE
を指定する必要があります。NOVALIDATE
はデフォルトのため、明示的に指定する必要はありません。
RELY
およびNORELY
パラメータはオプションです。ビュー制約は適用されないため、通常はRELY
パラメータで指定し、より有効に使用します。RELY
またはNORELY
キーワードは、DISABLE
キーワードより前に指定する必要があります。詳細は、「RELY句」を参照してください。
ビュー制約は直接適用されないため、INITIALLY
DEFERRED
またはDEFERRABLE
は指定できません。
using_index_clause
、exceptions_clause
句、またはreferences_clause
のON
DELETE
句は指定できません。
オブジェクト列の属性にビュー制約を定義することはできません。
例
一意キーの例 次の文は、サンプル表sh.promotions
を作成する文の例です。この文は制約を表内に定義し、promo_id
列で一意キーを暗黙的に使用可能にします(この例では、他の制約は省略されています)。
CREATE TABLE promotions_var1 ( promo_id NUMBER(6) CONSTRAINT promo_id_u UNIQUE , promo_name VARCHAR2(20) , promo_category VARCHAR2(15) , promo_cost NUMBER(10,2) , promo_begin_date DATE , promo_end_date DATE ) ;
制約promo_id_u
は、一意キーとしてpromo_id
列を識別します。この制約によって、表に同じIDを持つ複数の販売促進の行が存在しないことが保証されます。ただし、識別子のない行は許可されます。
この制約を表外に定義して使用可能にすることもできます。
CREATE TABLE promotions_var2 ( promo_id NUMBER(6) , promo_name VARCHAR2(20) , promo_category VARCHAR2(15) , promo_cost NUMBER(10,2) , promo_begin_date DATE , promo_end_date DATE , CONSTRAINT promo_id_u UNIQUE (promo_id) USING INDEX PCTFREE 20 TABLESPACE stocks STORAGE (INITIAL 8M) );
この文にはusing_index_clause
も含まれています。この句は、制約を使用可能にするために作成される索引の記憶特性を指定します。
複合一意キーの例 次の文は、oe.warehouses
表のwarehouse_id
列とwarehouse_name
列を組み合せて複合一意キーを定義し、使用可能にします。
ALTER TABLE warehouses ADD CONSTRAINT wh_unq UNIQUE (warehouse_id, warehouse_name) USING INDEX PCTFREE 5 EXCEPTIONS INTO wrong_id;
wh_unq
制約によって、warehouse_id
とwarehouse_name
を組み合せた値が表の中に複数存在しないことが保証されます。
このADD
CONSTRAINT
句には、制約以外のプロパティも指定できます。
USING
INDEX
句は、制約を使用可能にするために作成される索引の記憶特性を指定します。
EXCEPTIONS
INTO
句によって、制約に違反する行がwarehouses
表に含まれている場合、その行に関する情報がwrong_id
表に書き込まれます。wrong_id
例外表が存在しない場合、この文は正常に実行されません。
主キーの例 次の文は、サンプル表hr.locations
を作成する文の例です。locations_demo
表を作成し、location_id
列に主キーを定義して使用可能にします(この例では、hr.locations
表の他の制約は省略されています)。
CREATE TABLE locations_demo ( location_id NUMBER(4) CONSTRAINT loc_id_pk PRIMARY KEY , street_address VARCHAR2(40) , postal_code VARCHAR2(12) , city VARCHAR2(30) , state_province VARCHAR2(25) , country_id CHAR(2) ) ;
表内に指定されているloc_id_pk
制約は、location_id
列をlocations_demo
表の主キーとして識別します。この制約によって、表の中の複数の所在地が同一の所在地識別子を持つことはなく、かつ所在地識別子がNULL
にならないことが保証されます。
この制約を表外に定義して使用可能にすることもできます。
CREATE TABLE locations_demo ( location_id NUMBER(4) , street_address VARCHAR2(40) , postal_code VARCHAR2(12) , city VARCHAR2(30) , state_province VARCHAR2(25) , country_id CHAR(2) , CONSTRAINT loc_id_pk PRIMARY KEY (location_id));
NOT NULLの例 次の文は、(「主キーの例」で作成した)locations_demo
表を変更し、country_id
列にNOT
NULL
制約を定義して使用可能にします。
ALTER TABLE locations_demo MODIFY (country_id CONSTRAINT country_nn NOT NULL);
制約country_nn
によって、country_id
がNULLの所在地の行が表にないことが保証されます。
複合主キーの例 次の文は、sh.sales
サンプル表のprod_id
列およびcust_id
列を組み合せて複合主キーを定義します。
ALTER TABLE sales ADD CONSTRAINT sales_pk PRIMARY KEY (prod_id, cust_id) DISABLE;
この制約は、sales
表の主キーとしてprod_id
列とcust_id
列の組合せを識別します。この制約によって、表の中の複数の行がprod_id
列とcust_id
列に同じ組合せの値を持たないことが保証されます。
この制約句(PRIMARY
KEY
)では、次の制約のプロパティも指定しています。
制約定義によって制約名が指定されていないため、この制約に対する名前がOracleによって自動的に生成されます。
DISABLE
句によって制約が定義されますが、使用可能にはなりません。
外部キー制約の例 次の文は、dept_20
表を作成し、departments
表のdepartment_id
列の主キーを参照するdepartment_id
列に、外部キーを定義して使用可能にします。
CREATE TABLE dept_20 (employee_id NUMBER(4), last_name VARCHAR2(10), job_id VARCHAR2(9), manager_id NUMBER(4), hire_date DATE, salary NUMBER(7,2), commission_pct NUMBER(7,2), department_id CONSTRAINT fk_deptno REFERENCES departments(department_id) );
fk_deptno
制約によって、dept_20
表の従業員が属しているすべての部門がdepartments
表に含まれることが保証されます。ただし、部門番号がNULL値の従業員(どの部門にも属さない従業員)がいてもかまいません。すべての従業員がいずれかの部門に割り当てられるようにするには、dept_20
表のdepartment_id
列に対して、REFERENCES
制約の他にNOT
NULL
制約を作成します。
この制約を定義して使用可能にする前に、departments
表のdepartment_id
列を主キーまたは一意キーとして指定する制約を定義して使用可能にする必要があります。
制約が表内に定義されているため、この外部キー制約定義はFOREIGN
KEY
句を使用しません。また、この列には参照キーのデータ型が自動的に割り当てられるため、department_id
列のデータ型は必要ありません。
制約定義によって親表と参照キーの列の両方が指定されます。参照キーは親表の主キーであるため、参照キーの列名の指定は任意です。
この外部キー制約を表外に定義することもできます。
CREATE TABLE dept_20 (employee_id NUMBER(4), last_name VARCHAR2(10), job_id VARCHAR2(9), manager_id NUMBER(4), hire_date DATE, salary NUMBER(7,2), commission_pct NUMBER(7,2), department_id, CONSTRAINT fk_deptno FOREIGN KEY (department_id) REFERENCES departments(department_id) );
これらの外部キー定義は、両方ともON
DELETE
句を指定していないため、従業員がいる部門は削除できません。
ON DELETEの例 次の文では、dept_20
表を作成し、2つの参照整合性制約を定義して使用可能にした後、ON
DELETE
句を使用します。
CREATE TABLE dept_20 (employee_id NUMBER(4) PRIMARY KEY, last_name VARCHAR2(10), job_id VARCHAR2(9), manager_id NUMBER(4) CONSTRAINT fk_mgr REFERENCES employees ON DELETE SET NULL, hire_date DATE, salary NUMBER(7,2), commission_pct NUMBER(7,2), department_id NUMBER(2) CONSTRAINT fk_deptno REFERENCES departments(department_id) ON DELETE CASCADE );
最初のON
DELETE
句によって、従業員番号2332の上司がemployees
表から削除された場合、2332の上司の部下だったdept_20
表のすべての従業員のmanager_id
値がNULLになります。
次のON
DELETE
句によって、departments
表のdepartment_id
値が削除されると、これに依存するdept_20
表の行のdepartment_id
値も同時に削除されます。たとえば、部門番号20がdepartments
表から削除されると、部門番号20の全従業員がdept_20
表から削除されます。
複合外部キー制約の例 次の文は、dept_20
表のemployee_id
列およびhire_date
列を組み合せて外部キーを定義して使用可能にします。
ALTER TABLE dept_20 ADD CONSTRAINT fk_empid_hiredate FOREIGN KEY (employee_id, hire_date) REFERENCES hr.job_history(employee_id, start_date) EXCEPTIONS INTO wrong_emp;
fk_empid_hiredate
制約によって、dept_20
表の中すべての従業員が、employees
表に存在するemployee_id
とhire_date
の組合せを持つことが保証されます。この制約を定義して使用可能にする前に、employees
表のemployee_id
列とhire_date
列の組合せを主キーまたは一意キーとして指定する制約を定義して使用可能にする必要があります。
EXCEPTIONS
INTO
句によって、制約に違反する行がdept_20
表に含まれている場合、その行に関する情報がwrong_emp
表に書き込まれます。wrong_emp
例外表が存在しない場合、この文は正常に実行されません。
CHECK制約の例 次の文は、divisions
表を作成し、その表の各列にcheck
制約を定義します。
CREATE TABLE divisions (div_no NUMBER CONSTRAINT check_divno CHECK (div_no BETWEEN 10 AND 99) DISABLE, div_name VARCHAR2(9) CONSTRAINT check_divname CHECK (div_name = UPPER(div_name)) DISABLE, office VARCHAR2(10) CONSTRAINT check_office CHECK (office IN ('DALLAS','BOSTON', 'PARIS','TOKYO')) DISABLE);
列に定義されている各制約によって、列の値が次のように制限されます。
check_divno
によって、部門番号は必ず10から99の範囲内になります。
check_divname
によって、部門名はすべて大文字になります。
check_office
によって、事務所の所在地はDallas、Boston、ParisまたはTokyoのいずれかに制限されます。
それぞれのCONSTRAINT
句にDISABLE
句が指定されているため、これらの制約は定義されるのみで、使用可能にはされません。
次の文は、dept_20
表を作成し、CHECK制約を表外に定義して暗黙的に使用可能にします。
CREATE TABLE dept_20 (employee_id NUMBER(4) PRIMARY KEY, last_name VARCHAR2(10), job_id VARCHAR2(9), manager_id NUMBER(4), salary NUMBER(7,2), commission_pct NUMBER(7,2), department_id NUMBER(2), CONSTRAINT check_sal CHECK (salary * commission_pct <= 5000));
この制約は、不等式の条件を使用して、従業員の歩合総額(salary
とcommission_pct
を掛けた金額)を$5000に制限します。
従業員の給与と歩合がNULL以外の値の場合、制約を満たすには、この金額が$5000を超えてはいけません。
従業員の給与または歩合がNULL値の場合、条件の結果は不明となり、その従業員は自動的に制約を満たします。
この例の制約句には制約名が指定されていないため、制約の名前が自動的に生成されます。
次の文は、1つの主キー制約、2つの外部キー制約、1つのNOT
NULL
制約および2つのCHECK制約を定義して使用可能にします。
CREATE TABLE order_detail (CONSTRAINT pk_od PRIMARY KEY (order_id, part_no), order_id NUMBER CONSTRAINT fk_oid REFERENCES oe.orders(order_id), part_no NUMBER CONSTRAINT fk_pno REFERENCES oe.product_information(product_id), quantity NUMBER CONSTRAINT nn_qty NOT NULL CONSTRAINT check_qty CHECK (quantity > 0), cost NUMBER CONSTRAINT check_cost CHECK (cost > 0) );
この制約によって、表のデータに対して次の規則を適用できます。
pk_od
は、order_id
列とpart_no
列の組合せを表の主キーとして指定します。この制約を満たすためには、order_id
列およびpart_no
列の組合せが同じである行が、表内に2つあってはいけません。また、order_id
列およびpart_no
列では、行にNULLを入れることはできません。
fk_oid
は、サンプル・スキーマoe
内のorders
表にあるorder_id
列を参照する外部キーとして、order_id
列を指定します。order_detail
.order_id
列に追加されるすべての新しい値は、oe.orders.order_id
列にあらかじめ存在する必要があります。
fk_pno
は、oe
が所有するproduct_information
表にあるproduct_id
列を参照する外部キーとして、product_id
列を指定します。order_detail.product_id
列に追加されるすべての新しい値は、oe.product_information.product_id
列にあらかじめ存在する必要があります。
nn_qty
は、quantity
列に対してNULLを禁止します。
check_qty
によって、quantity
列の値は必ず0(ゼロ)より大きくなります。
check_cost
によって、cost列の値は必ず0(ゼロ)より大きくなります。
この例は、制約句と列定義について、次の点についても示しています。
表外制約定義は、列定義の前と後のどちらにも指定できます。この例では、pk_od
制約の表外定義が、列定義の前にあります。
列定義には、複数の表内制約定義を含めることができます。この例では、quantity
列の定義はnn_qty
制約とcheck_qty
制約の両方の定義を含んでいます。
表には、複数のCHECK
制約を指定できます。複数のビジネス・ルールを適用する複雑な条件を持つ1つのCHECK
制約よりも、それぞれ1つのビジネス・ルールのみを適用する単純な条件を持つ複数のCHECK
制約を使用してください。矛盾している制約があると、その制約を識別するエラー・メッセージが戻されます。エラーが検出された制約が1つのビジネス・ルールのみを有効にする場合、このようなエラー・メッセージの方が、矛盾のあるビジネス・ルールを正確に識別できます。
属性レベル制約の例 次の文は、students
表のname
列のfirst_name
属性とlast_name
属性の両方に対して値が存在することを保証します。
CREATE TYPE person_name AS OBJECT (first_name VARCHAR2(30), last_name VARCHAR2(30)); / CREATE TABLE students (name person_name, age INTEGER, CHECK (name.first_name IS NOT NULL AND name.last_name IS NOT NULL));
REF制約の例 次の例は、サンプル・スキーマのオブジェクト型であるcust_address_typ
の複製を作成し、SCOPE
制約が指定されたREF
列を含む表を作成します。
CREATE TYPE cust_address_typ_new AS OBJECT ( street_address VARCHAR2(40) , postal_code VARCHAR2(10) , city VARCHAR2(30) , state_province VARCHAR2(10) , country_id CHAR(2) ); / CREATE TABLE address_table OF cust_address_typ_new; CREATE TABLE customer_addresses ( add_id NUMBER, address REF cust_address_typ_new SCOPE IS address_table);
次の例は、同じ表を作成しますが、親表のオブジェクト識別子列を参照するREF
列に参照整合性制約が指定されています。
CREATE TABLE customer_addresses ( add_id NUMBER, address REF cust_address_typ REFERENCES address_table);
次の例では、department_typ
型およびdepartments_obj_t
表(「オブジェクト表の作成例:」で作成)を使用します。この文を実行すると、有効範囲付きREF
を持つ表が作成されます。
CREATE TABLE employees_obj ( e_name VARCHAR2(100), e_number NUMBER, e_dept REF department_typ SCOPE IS departments_obj_t );
次の文は、参照整合性制約が定義されているREF
列を含む表を作成します。
CREATE TABLE employees_obj ( e_name VARCHAR2(100), e_number NUMBER, e_dept REF department_typ REFERENCES departments_obj_t);
明示的な索引の制御例 次の文は、Oracleが制約を適用する場合に使用する索引を、明示的に制御する一意制約または主キー制約を作成する別の方法を示します。
CREATE TABLE promotions_var3 ( promo_id NUMBER(6) , promo_name VARCHAR2(20) , promo_category VARCHAR2(15) , promo_cost NUMBER(10,2) , promo_begin_date DATE , promo_end_date DATE , CONSTRAINT promo_id_u UNIQUE (promo_id, promo_cost) USING INDEX (CREATE UNIQUE INDEX promo_ix1 ON promotions_var3 (promo_id, promo_cost)) , CONSTRAINT promo_id_u2 UNIQUE (promo_cost, promo_id) USING INDEX promo_ix1);
この例は、1つの制約に対して1つの索引を作成し、その索引を使用して同じ文に別の制約を作成して使用可能にできることも示しています。
DEFERRABLE制約の例 次の文は、scores
列にCHECK制約NOT
DEFERRABLE
INITIALLY
IMMEDIATE
(デフォルト)を使用したgames
表を作成します。
CREATE TABLE games (scores NUMBER CHECK (scores >= 0));
次の文は、列に対する一意制約をINITIALLY
DEFERRED
DEFERRABLE
として定義します。
CREATE TABLE games (scores NUMBER, CONSTRAINT unq_num UNIQUE (scores) INITIALLY DEFERRED DEFERRABLE);