日本語PDF

5 データ整合性

この章では、整合性制約によって、データベースに関連するビジネス・ルールがどのように規定され、表への無効なエントリがどのように防止されるかについて説明します。

この章の構成は、次のとおりです。

関連項目:

列の背景と整合性制約の必要性については、表の概要を参照

データ整合性の概要

データベース管理者やアプリケーション開発者が決定したビジネス・ルールに準拠し、データ整合性を維持するのは重要なことです。

ビジネス・ルールでは、常に真(true)となる必要がある、または常に偽(false)となる必要がある条件および関係を定義します。たとえば、各企業では、給与、従業員番号、在庫追跡などに関して独自のポリシーを定義します。

データ整合性を保証する方法

データベース・アプリケーションを設計する場合、開発者は、データベースに格納するデータの整合性を保証するためのいくつかのオプションを使用できます。

このオプションには次のものがあります。

  • トリガーされるストアド・データベース・プロシージャを使用して、ビジネス・ルールを規定します

  • ストアド・プロシージャを使用してデータへのアクセスを完全に制御します

  • データベース・アプリケーションのコードでビジネス・ルールを規定します。

  • 列またはオブジェクト・レベルで定義される、データベースの値を制限する規則である、Oracle Databaseの整合性制約を使用します。

関連項目:

整合性制約の利点

整合性制約は、SQLを使用して作成および削除されるスキーマ・オブジェクトです。データ整合性を維持するために、可能な場合は常に、整合性制約を使用するようにしてください。

データ整合性を維持する方法として、整合性制約には、次のような利点があります。

  • 宣言の容易さ

    SQL文を使用して整合性制約を定義するため、追加のプログラミングなしに表を定義または変更できます。SQL文は記述が容易で、プログラミングのエラーを避けられます。

  • 規則の集中化

    整合性制約は表に対して定義され、データ・ディクショナリに格納されます。したがって、すべてのアプリケーションから入力されるデータは、同じ整合性制約を遵守する必要があります。規則が表レベルで変化した場合も、アプリケーションを変更する必要はありません。また、データベースによってSQL文がチェックされる前に、アプリケーションがデータ・ディクショナリのメタデータを使用して、すぐにユーザーに違反を通知することもできます。

  • データをロードする場合の柔軟性

    大量のデータをロードする場合は、パフォーマンスのオーバーヘッドを回避するために、整合性制約を一時的に無効にできます。データ・ロードが完了した後、整合性制約を再度有効にできます。

関連項目:

整合性制約のタイプ

Oracle Databaseでは、表と列の両方のレベルで制約を適用できます。

列または属性の一部として指定される制約が、表内指定です。表定義の一部として指定される制約が、表外指定です。

キーとは、特定タイプの整合性制約の定義に含まれる列または列の集合です。キーによって、リレーショナル・データベースの表と列の間の関連が示されます。キーの中にある個々の値を、キー値と呼びます。

次の表に、制約のタイプを示します。表内指定であることが必要なNOT NULLを除き、どの制約も表内と表外のいずれかで指定できます。

表5-1 整合性制約のタイプ

制約タイプ 説明 関連項目

NOT NULL

指定した列でのNULLを含む行の挿入または更新を許可または禁止します。

「NOT NULL整合性制約」

一意キー

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

一意制約

主キー

NOT NULL制約と一意制約を結合します。同じ列または列の組合せで、複数の行が同じ値を持つことを禁止し、値がNULLであることを禁止します。

主キー制約

外部キー

列を外部キーに指定し、外部キーと、参照キーと呼ばれる主キーまたは一意キーの間の関係を確立します。

外部キー制約

チェック

指定した条件をデータベース値が満たしている必要があります。

チェック制約

REF

REF列の値で許可されるデータ操作のタイプ、およびその操作の結果として依存データが受ける影響について指示します。オブジェクト・リレーショナル・データベースでは、REFと呼ばれる組込みデータ型によって、指定したオブジェクト型の行オブジェクトへの参照がカプセル化されます。REF列に対する参照整合性制約によって、REFの行オブジェクトがあることが保証されます。

REF制約の詳細は、『Oracle Databaseオブジェクト・リレーショナル開発者ガイド』を参照してください。

関連項目:

NOT NULL整合性制約

NOT NULL制約がある場合、表の列値にNULLを使用できません。NULLは、値がないことを示します。デフォルトでは、表のすべての列でNULLを使用できます。

NOT NULL制約は、値が必須である列のためのものです。たとえば、hr.employees表ではemail列に値が必要です。電子メール・アドレスなしで従業員の行を挿入しようとすると、次のエラーが発生します。

SQL> INSERT INTO hr.employees (employee_id, last_name) values (999, 'Smith');
.
.
.
ERROR at line 1:
ORA-01400: cannot insert NULL into ("HR"."EMPLOYEES"."EMAIL")

NOT NULL制約を持つ列は、行が1つも含まれていない表またはデフォルト値が指定された表にのみ追加できます。

関連項目:

一意制約

一意キー制約では、列(または列の集合)のすべての値が一意である必要があります。一意キー制約が設定されていると、表の行では、列(一意キー)または列の集合(コンポジット一意キー)で重複する値を持つことはありません。

注意:

キーという用語は、整合性制約で定義されている列のみを指します。データベースではキー列に対して索引を暗黙的に作成または再利用することで一意制約による規制を規定するため、一意キーという用語は一意キー制約または一意索引のシノニムとして誤用されることがあります。

一意キー制約は、任意の列に重複する値が格納されないようにする場合に適しています。一意制約は、(各表の行を一意に識別することが目的である)主キー制約とは異なり、通常は、一意であること以外の意味を持たない値が含まれています。一意キーの例には次のものがあります。

  • 主キーが顧客番号である場合の、顧客電話番号

  • 主キーが部門番号である場合の、部門名

例2-1に示すように、hr.employees表のemail列には一意キー制約が存在します。文の関連する部分は、次のとおりです。

CREATE TABLE employees    ( ...
    , email          VARCHAR2(25)
        CONSTRAINT   emp_email_nn  NOT NULL ...
    , CONSTRAINT     emp_email_uk  UNIQUE (email) ... );

次の例に示すように、emp_email_uk制約により、2人の従業員が同じ電子メール・アドレスを持つことはありません。

SQL> SELECT employee_id, last_name, email FROM employees WHERE email = 'PFAY';
 
EMPLOYEE_ID LAST_NAME                 EMAIL
----------- ------------------------- -------------------------
        202 Fay                       PFAY

SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)    
  1  VALUES (999,'Fay','PFAY',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMAIL_UK) violated

NOT NULL制約も定義されている場合を除き、一意キー制約では、NULLは常に許可されます。このため、一意キー制約とNOT NULL制約の両方を持つ列が一般的に使用されます。これらの組合せにより、ユーザーは一意キーに必ず値を入力することになり、さらに新しい行データが既存の行データと競合することがなくなります。

注意:

複数の列に対する一意キー制約の検索メカニズムにより、一部がNULLのコンポジット一意キー制約の非NULL列で同一の値は許されません。

例5-1 一意制約

SQL> SELECT employee_id, last_name, email FROM employees WHERE email = 'PFAY';
 
EMPLOYEE_ID LAST_NAME                 EMAIL
----------- ------------------------- -------------------------
        202 Fay                       PFAY

SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)    
  1  VALUES (999,'Fay','PFAY',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMAIL_UK) violated

関連項目:

主キー制約

主キー制約を設定すると、この制約の対象となる1つ以上の列グループの値によって、行が一意に識別されます。各表には1つの主キーを設定でき、この主キーによって行が識別され、行が重複しないことが保証されます。

主キーには、自然キーまたはサロゲート・キーを使用できます。自然キーは、表内の既存の属性から作成される、意味のある識別子です。たとえば、参照表の郵便番号を自然キーとして使用できます。これに対して、サロゲート・キーは、システムで生成され、値が増加する識別子で、この識別子によって表内での一意性が保たれます。通常、サロゲート・キーは順序によって生成されます。

Oracle Databaseでは、主キー制約の実装により、次のことが保証されます。

  • 指定された列または列の集合の中に、2つの行が重複する値を持つことはありません。

  • 主キー列では、NULLは許可されません。

主キーが必要となる典型的な状況は、従業員用の数値識別子です。各従業員は、一意のIDを持つ必要があります。従業員は、employees表の1つの行によってのみ記述する必要があります。

「一意制約」の例では、既存の従業員が従業員IDとして202を持っており、従業員IDが主キーであることが示されています。次に示す例では、同じ従業員IDを持つ従業員、およびIDを持たない従業員を追加します。

SQL> INSERT INTO employees (employee_id, last_name, email, hire_date, job_id)    
  1  VALUES (202,'Chan','JCHAN',SYSDATE,'ST_CLERK');
.
.
.
ERROR at line 1:
ORA-00001: unique constraint (HR.EMP_EMP_ID_PK) violated

SQL> INSERT INTO employees (last_name) VALUES ('Chan');
.
.
.
ERROR at line 1:
ORA-01400: cannot insert NULL into ("HR"."EMPLOYEES"."EMPLOYEE_ID")

データベースにより、索引を持つ主キー制約が規定されます。通常、列に対して作成された主キー制約によって、暗黙的に一意索引とNOT NULL制約が作成されます。この規則には、次の例外がある点に注意してください。

  • 場合によっては、遅延可能制約を使用して主キーを作成する場合、生成された索引は一意ではありません。

    注意:

    CREATE UNIQUE INDEX文を使用すると、一意の索引を明示的に作成できます。

  • 主キー制約の作成時に使用できる索引がある場合、制約ではこの索引を再利用し、索引を暗黙的に作成することはありません。

デフォルトでは、暗黙的に作成された索引の名前が、主キー制約の名前になります。索引にはユーザー定義名を指定することもできます。制約の作成に使用するCREATE TABLE文またはALTER TABLE文にENABLE句を組み込んで、索引の記憶域オプションを指定できます。

関連項目:

表に主キー制約を追加する方法の詳細は、Oracle Database 2日で開発者ガイドおよびOracle Database開発ガイドを参照してください

外部キー制約

2つの表に1つ以上の共通の列が含まれる場合、Oracle Databaseでは、参照整合性制約とも呼ばれる外部キー制約を介して2つの表の間の関係を規定できます。

外部キー制約では、制約が定義される列の各値に対して、他の表と列を指定するもう一方の列の値が一致する必要があります。参照整合性規則の例としては、既存の部門にのみ従事できる従業員があります。

次の表に、参照整合性制約に関連する用語を示します。

表5-2 参照整合性制約の用語

用語 定義

外部キー

制約の定義に含まれている列または列の集合のうち、参照キーを参照するもの。たとえば、employeesdepartment_id列は外部キーであり、departmentsdepartment_id列を参照します。

外部キーは、複数列として定義できます。ただし、コンポジット外部キーの列数とデータ型は、参照先のコンポジット主キーまたは一意キーと同じであることが必要です。

外部キーの値は、参照先の主キーまたは一意キーの値と一致するか、NULLであることが可能です。コンポジット外部キーのいずれかの列がNULLの場合、そのキーのNULL以外の部分は、親キーの対応部分と一致している必要はありません。

参照キー

表の一意キーまたは主キーで、外部キーによって参照されるキー。たとえば、departmentsdepartment_id列は、employeesdepartment_id列の参照キーです。

依存表または子表

外部キーを含む表。この表は、参照される一意キーまたは主キーにある値に依存しています。たとえば、employees表はdepartmentsの子です。

参照表または親表

子表の外部キーが参照する表。この表の参照キーによって、子表に対する特定の挿入または更新が許可されるかどうかが決まります。たとえば、departments表はemployeesの親です。

図5-1に、employees.department_id列の外部キーを示します。この列のすべての値が、departments.department_id列の値と一致することが保証されます。このため、employees.department_id列に間違った部門番号が存在することはありません。

図5-1 参照整合性制約

図5-1の説明が続きます
「図5-1 参照整合性制約」の説明

関連項目:

表に外部キー制約を追加する方法の詳細は、Oracle Database 2日で開発者ガイドおよびOracle Database開発ガイドを参照してください

自己参照型整合性制約

自己参照型整合性制約は、同じ表の親キーを参照する外部キーです。

次の図では、自己参照型制約によって、employees.manager_id列のすべての値が、employees.employee_id列の既存の値に対応するようになります。たとえば、従業員102の管理職がemployees表に存在する必要があります。この制約によって、間違った従業員番号がmanager_id列に存在する可能性がなくなります。

図5-2 単一表の参照制約

図5-2の説明が続きます
「図5-2 単一表の参照制約」の説明
NULLと外部キー

リレーショナル・モデルでは、外部キーの値は、参照先の主キーまたは一意キーの値と一致するか、NULLであることが可能です。たとえば、hr.employeesの行で部門IDが指定されないことがあります。

コンポジット外部キーのいずれかの列がNULLの場合、そのキーのNULL以外の部分は、親キーの対応部分と一致している必要はありません。たとえば、reservations表のtable_id列およびdate列にはコンポジット外部キーが含まれるが、table_idはNULLであることがあります。

親キーの修正と外部キー

親キーを削除するとき、外部キーと親キーの間の関係が影響を及ぼします。たとえば、あるユーザーが部門のレコードの削除を試行すると、この部門の従業員のレコードに何が起こるかについて説明します。

親キーが変更された場合、参照整合性制約では、子表の依存行に対して実行される次のアクションを指定できます。

  • 削除または更新に対するアクションなし

    通常、結果が参照整合性に違反する場合、ユーザーは参照キー値を変更できません。たとえば、employees.department_iddepartmentsに対する外部キーであり、従業員が特定の部門に属す場合、この部門の行の削除を試行すると、制約に対する違反となります。

  • 連鎖的な削除

    参照キー値を含む行が削除された場合、子表のうち依存している外部キー値を含むすべての行も削除されます(DELETE CASCADE)。たとえば、departmentsの行を削除すると、この部門のすべての従業員の行が削除されます。

  • NULLを設定する削除

    参照キー値を含む行が削除された場合に、子表のうち依存している外部キー値を含むすべての行の値がNULLに設定されます(DELETE SET NULL)。たとえば、部門の行を削除すると、この部門のすべての従業員に関してdepartment_id列値がNULLに設定されます。

表5-3に、親表のキー値および子表の外部キー値に対する異なる参照アクションごとに可能なDML文の概要を示します。

表5-3 UPDATE NO ACTIONとDELETE NO ACTIONで許可されるDML文

DML文 親表に対して発行 子表に対して発行

INSERT

親キー値が一意であれば常に発行できます。

外部キーの値が親キーに存在するか、外部キーの一部またはすべてがNULLの場合にのみ発行できます。

UPDATE NO ACTION

文の実行後に、参照される親キー値のない行が子表内に残らない場合は発行できます。

文の実行後も新しい外部キー値によって参照キー値が参照される場合は発行できます。

DELETE NO ACTION

子表のどの行も親キー値を参照していない場合は発行できます。

常に発行可能

DELETE CASCADE

常に発行可能

常に発行可能

DELETE SET NULL

常に発行可能

常に発行可能

注意:

Oracle Databaseの外部キー整合性制約でサポートされていない他の参照アクションは、データベース・トリガーを使用して規定できます。「トリガーの概要」を参照してください。

関連項目:

ON DELETE句の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

索引と外部キー

通常、外部キーには索引付けが必要です。唯一の例外は、対応する一意キーまたは主キーの更新や削除が発生しないことが確実な場合です。

子表で外部キーの索引付けを行うと、次の利点があります。

  • 子表に対する完全表ロックが防止されます。かわりに、データベースは索引に対する行ロックを取得します。

  • 子表の全表スキャンを行う必要がなくなります。例として、ユーザーがdepartments表から部門10のレコードを削除する場合を想定します。employees.department_idが索引付けされていない場合、データベースはemployeesをスキャンして、部門10に従業員が存在するかどうかを確認する必要があります。

関連項目:

  • ロックと外部キーでは、索引付き外部キー列と索引なしの外部キー列のロック動作について説明します

  • 索引の概要では、索引の目的および特性について説明します

チェック制約

列または列の集合に対するチェック制約では、すべての行について、指定した条件がTRUEまたはUNKNOWNであることが必要です。

DMLの結果で制約の条件がFALSEに評価される場合、そのSQL文はロールバックされます。チェック制約の主な利点は、特殊な整合性規則を規定できることです。たとえば、チェック制約を使用すると、hr.employees表に次の規則を規定できます。

  • salary列の値は10000以下である必要があります。

  • commission列の値は、salaryの値以下である必要があります。

次の例では、employeesに最大給与制約を作成し、最大値を超える給与を含む行を文で挿入すると、どのようなことが起こるかを示します。

SQL> ALTER TABLE employees ADD CONSTRAINT max_emp_sal CHECK (salary < 10001);
SQL> INSERT INTO employees (employee_id,last_name,email,hire_date,job_id,salary)
  1  VALUES (999,'Green','BGREEN',SYSDATE,'ST_CLERK',20000);
.
.
.
ERROR at line 1:
ORA-02290: check constraint (HR.MAX_EMP_SAL) violated

1つの列に、定義された列を参照する複数のチェック制約を設定できます。たとえば、salary列には、10000より大きい値を禁止する1つの制約と、500未満の値を禁止する別の制約を設定できます。

単一の列に対して複数のチェック制約が存在する場合は、その目的が競合しないように設計する必要があります。また、条件は特定の順序では評価されません。データベースでは、チェック条件が矛盾しないかどうかは検証されません。

関連項目:

チェック制約の制限の詳細は、Oracle Database SQL言語リファレンスを参照してください。

整合性制約の状態

制約定義の一部として、Oracle Databaseがいつどのようにして制約を規定するかを指定できます。これにより、制約状態が決定します。

変更されたデータおよび既存のデータのチェック

データベースでは、制約が既存のデータまたは将来のデータに適用されるかどうかを指定できます。制約が使用可能である場合、データベースは、入力または更新の時点での新規データをチェックします。制約に準拠しないデータをデータベースに入力することはできません。

たとえば、employees.department_idに対してNOT NULL制約を使用可能にすると、将来のすべての行が部門IDを持ちます。制約が使用禁止である場合、表には制約に違反する行を入力できます。

制約は次の検証モードのいずれかに設定できます。

  • VALIDATE

    既存のデータは制約に準拠する必要があります。たとえば、employees.department_idに対してNOT NULL制約を使用可能にし、この制約をVALIDATEに設定すると、既存のすべての行が部門IDを持つことをチェックできます。

  • NOVALIDATE

    既存のデータは制約に準拠する必要がありません。実際には、これは"信頼"モードです。たとえば、表にロードされたすべての売上に日付がある場合、日付列にNOT NULL制約を作成し、制約をNOVALIDATEに設定できます。適用されない制約は、通常、マテリアライズド・ビューおよびクエリー・リライトにのみ有効です。

    NOVALIDATEモードの制約の場合、RELYパラメータは、オプティマイザが制約を使用して結合情報を判別できることを示します。制約はデータの検証には使用されませんが、マテリアライズド・ビューのより高度なクエリー・リライトを可能にし、データ・ウェアハウス・ツールによってデータ・ディクショナリから制約情報を取得できます。デフォルトはNORELYです。これは、オプティマイザが実際には制約を認識しないことを意味します。

VALIDATEおよびNOVALIDATEの動作は、常に、制約が使用可能であるか使用禁止であるかどうかによって異なります。次の表に関係をまとめます。

表5-4 変更されたデータおよび既存のデータのチェック

変更されたデータ 既存のデータ サマリー

ENABLE

VALIDATE

既存のデータと将来のデータは制約に準拠する必要があります。データが入力されている表に新しい制約を適用しようとすると、既存の行がその制約に違反する場合、エラーになります。

ENABLE

NOVALIDATE

データベースは制約をチェックしますが、制約はすべての行に関してTRUEである必要はありません。このため、既存の行が制約に違反している可能性はありますが、新しい行または変更された行は規則に準拠する必要があります。このモードは、整合性がすでに検証されている既存のデータを含むデータ・ウェアハウスで使用されます。

DISABLE

VALIDATE

データベースでは制約が使用禁止になり、索引が削除されて、制約の対象となる列への変更が禁止されます。

DISABLE

NOVALIDATE

制約はチェックされず、TRUEでなくてもかまいません。

関連項目:

制約の状態の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

データベースが制約の妥当性をチェックするタイミング

あらゆる制約は、遅延不可状態(デフォルト)または遅延可能状態のいずれかにあります。この状態によって、Oracle Databaseが妥当性を確認するためにどの時点で制約をチェックするかが決まります。

次の図は、遅延可能制約のオプションを示します。

図5-3 遅延可能制約のオプション

図5-3の説明が続きます
「図5-3 遅延可能制約のオプション」の説明
遅延不可制約

遅延不可制約では、Oracle Databaseは、制約の妥当性チェックをトランザクションの最後まで遅延することはありません。かわりに、データベースでは各文の最後で制約をチェックします。制約に違反している場合、その文はロールバックします。

たとえば、employees.last_name列用に遅延不可のNOT NULL制約が存在します。セッションが姓のない行を挿入しようとすると、NOT NULL制約に違反しているため、データベースはただちに文をロールバックします。行は挿入されません。

遅延可能制約

遅延可能制約を使用すると、トランザクションでSET CONSTRAINT句を使用して、COMMIT文が発行されるまでこの制約のチェックを遅延させることができます。制約に違反している可能性があるデータベースを変更する場合、この設定により、すべての変更が完了するまで制約を事実上無効にすることができます。

データベースが遅延可能制約をチェックする時点に関して、デフォルト動作を設定できます。次のいずれかの属性を指定できます。

  • INITIALLY IMMEDIATE

    データベースは、各文の実行直後に制約をチェックします。制約に違反している場合、データベースは文をロールバックします。

  • INITIALLY DEFERRED

    データベースは、COMMITが発行された時点で制約をチェックします。制約に違反している場合、データベースはトランザクションをロールバックします。

employees.last_nameに対する遅延可能なNOT NULL制約がINITIALLY DEFERREDに設定されているとします。ユーザーは100個のINSERT文を含むトランザクションを作成し、その一部にはlast_nameとしてNULL値があります。ユーザーがコミットしようとすると、データベースは100個すべての文をロールバックします。ただし、この制約がINITIALLY IMMEDIATEに設定されている場合、データベースはトランザクションをロールバックしません。

制約によってアクションが発生する場合は、遅延制約か即時制約かに関係なく、このアクションはアクションを発生させた文の一部とみなされます。たとえば、departmentsの行を削除すると、削除された部門の行を参照するemployeesのすべての行が削除されます。この場合、employeesからの削除は、departmentsに対して実行されたDELETE文の一部とみなされます。

関連項目:

制約属性とそのデフォルト値の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

制約チェックの例

次の例では、Oracle Databaseが制約のチェックをどの時点で実行するかを示します。

この例では、次のような状況を想定します。

  • employees表は、自己参照型整合性制約に示した構造を持っています。

  • 自己参照型制約によって、manager_id列のエントリがemployee_id列の値に依存しています。

例: 親キー値が存在しない時点での外部キー列での値の挿入

この例では、employees表に最初の行を挿入する場合を考えます。現在は行が存在しないため、manager_id列の値がemployee_id列の既存の値を参照できない場合に行を入力する方法を考えなくてはなりません。

次の方法が考えられます。

  • manager_id列にNOT NULL制約が定義されていない場合には、第1行のmanager_id列にnullを入力できます。

    外部キーにはnullが許されるため、Oracle Databaseではこの行を表に挿入します。

  • 同じ値をemployee_id列およびmanager_id列に入力でき、これは、その従業員が管理職であることを示します。

    このことから、Oracle Databaseが文の実行に制約チェックを実行することがわかります。親キーと外部キーに同じ値を指定した行の入力を許可するために、データベースは、まず新しい行を挿入してから、その新しい行のmanager_idに対応するemployee_idのある行がその表に含まれているかどうかをチェックします。

  • SELECT文のネストを伴うINSERT文など、複数行を挿入するINSERT文により、相互に参照しあう行を挿入できます。

    たとえば、第1行には従業員IDとして200、管理職IDとして300が含まれており、第2行には従業員IDとして300、管理職IDとして200が含まれているとします。制約チェックはINSERT文の実行が完了するまで遅延されています。すべての行が挿入されてから、制約違反がないかどうかすべての行がチェックされます。

デフォルト値は、文の解析前にINSERT文の一部として組み込まれます。このため、デフォルトの列値はすべての整合性制約チェックの対象になります。

例: すべての外部キー値および親キー値の更新

この例では、自己参照型制約によって、employeesmanager_id列のエントリがemployee_id列の値に依存しています。

会社が買収された場合です。この買収に伴い、すべての従業員番号の現在の設定値に5000を加算して、新しい会社の従業員番号と調和させる必要があります。次の図に示すように、一部の従業員は管理職でもあります。

図5-4 更新前のemployees表

図5-4の説明が続きます
「図5-4 更新前のemployees表」の説明

管理職番号は従業員番号でもあるため、管理職番号にも5000を加算する必要があります。次のSQL文を実行すると値を更新できます。

UPDATE employees SET employee_id = employee_id + 5000,
  manager_id = manager_id + 5000;

制約は、各manager_id値がemployee_id値と一致するかどうかを検証するように定義されていますが、データベースでは文の完了後に制約チェックが効率的に実行されるため、前述の文は有効です。図5-5に、データベースでは、制約をチェックする前に、SQL文全体のアクションが実行されることを示します。

この項の例は、INSERT文とUPDATE文を実行した場合の制約チェックのメカニズムを示していますが、データベースでは同じメカニズムがすべてのタイプのDML文に使用されます。同じメカニズムが、自己参照型制約のみでなく、すべてのタイプの制約に使用されます。

注意:

ビューまたはシノニムに対する操作は、実表に定義されている整合性制約に従います。