7.2 型依存性
型依存性は大きく次の2つのカテゴリに分かれます。
-
型が定義に対して相互に依存し、一方の型が他方の型の定義の一部である可能性がある状況。
-
型の作成または削除が表や型などの型が持つ依存性によって複雑になる状況。
この項の内容は次のとおりです。
7.2.1 不完全な型の作成
直接的または中間の型を介して定義に対して互いに依存する型を、相互依存といいます。たとえば、employee
の1つの属性を従業員が属する部門にし、department
の1つの属性を部門を管理する従業員にするように、オブジェクト型employee
およびdepartment
を定義できます。
矢印を使用して一連の相互依存型の関係を示す図を視覚化する場合、つながりがループを形成します。そのような循環依存を定義するには、サークルの最小限1つのセグメントにREF
を使用する必要があります。
たとえば、例7-7に示す型を定義できます。
例7-7 依存オブジェクト型の作成
-- Requires Ex. 7-1 and password CONNECT user1 -- Enter password ALTER SESSION SET PLSQL_WARNINGS = 'enable:all'; CREATE TYPE department; // a placeholder / CREATE TYPE employee AS OBJECT ( name VARCHAR2(30), dept REF department, supv REF employee ); / CREATE TYPE emp_list AS TABLE OF employee; / CREATE TYPE department AS OBJECT ( name VARCHAR2(30), mgr REF employee, staff emp_list ); /
これは、適切な相互依存型におけるSQL DDL文の適切な順序です。これをエラーなしでコンパイルします。
例7-7のコードはdepartment
型を2回作成することに注意してください。最初の文は、employee
のREF
属性が指すプレースホルダとして機能するdepartment
の不完全な宣言です。AS
OBJECT
句が省略され、属性またはメソッドがリストされていない点で、この宣言は不完全です。これらは、後述の型を完成させる完全な宣言で指定します。ここでは、department
を不完全なオブジェクト型として作成しておきます。これにより、employee
がエラーなしでコンパイルできます。
不完全な型をプレースホルダとして作成しない場合、その型を参照する型はコンパイルされますが、コンパイル・エラーが発生します。たとえば、department
が存在しない場合、それを不完全な型として作成し、employee
はコンパイル・エラーになります。この場合、次回なんらかの操作がこの型にアクセスする際に、employee
が再コンパイルされます。この型が依存するすべての型が作成され、その依存性が完全な場合、エラーなしでコンパイルされます。
不完全な型を使用することにより、まだ作成されていないサブタイプに対するREF
属性を格納する型も作成できます。こうしたスーパータイプを作成するには、参照するサブタイプの不完全な型を最初に作成します。完全なサブタイプは、スーパータイプ作成後に作成します。
7.2.2 不完全な型の再定義
不完全な型が参照するすべての型を作成したら、不完全な型が不完全な状態を維持する必要がなくなるため、不完全な型の宣言を再定義してください。
型を再定義すると、型が再コンパイルされ、システムが様々なロックを解放できるようになります。型は、CREATE
TYPE
文を使用して再定義します。
-
例7-7の最後に示すとおり、型の属性およびメソッドを指定する
CREATE
TYPE
文を実行します。
データベースによって作成される不完全な型も再定義する必要があります。前述の項で説明したように、不完全な型としてdepartment
を明示的に作成しなかった場合、データベースによって作成されました。この場合、引き続き再定義する必要があります。
不完全なオブジェクト型は、オブジェクト型として再定義する必要があります。オブジェクト型をコレクション型(ネストした表型または配列型)として再定義することはできません。その型を削除することはできます。
7.2.3 手動による型の再コンパイル
型の作成でコンパイル・エラーが発生し、その型に対してなんらかの操作(表の作成、行の挿入など)を実行しようとした場合、エラーが発生することがあります。この操作を行う前に、タイプを再コンパイルする必要があります。ALTER
TYPE
文を使用して再コンパイルします。
-
ALTER
TYPE
typename
COMPILE
文を実行します。型のコンパイルが正常に実行された後、操作を再試行してください。
7.2.4 型および表の依存性がある場合のCREATE OR REPLACE TYPEの使用
CREATE
OR
REPLACE
TYPE
文は、置換される型に表または型の依存性がある場合にエラーをスローします。これは、オブジェクト、VARRAYおよびネストした表の型に適用されます。また、継承または型の合成(一方の型をもう一方の型に埋め込む)に関連する型の依存性にも適用されます。継承または型の合成では、一方の型がもう一方の属性である場合があります。
CREATE
OR
REPLACE
TYPE
文でFORCE
オプションを使用すると、型の依存性がある場合に型を置換できますが、表の依存性がある場合には置換できません。表の依存性はエラーの原因になります。
-
型の依存性がある場合は、
FORCE
オプションをCREATE
OR
REPLACE
TYPE
文で使用して型を置換します。
例7-8に、型の依存性が原因で失敗するCREATE
OR
REPLACE
文を示します。
例7-8 CREATE OR REPLACEの型と表のエラー
SQL> CREATE type t1 AS OBJECT (a number) not final;
2 /
Type created.
SQL> CREATE TYPE t2 UNDER t1 (b varchar(10));
2 /
Type created.
SQL> CREATE OR REPLACE TYPE t1 AS OBJECT (c varchar(20));
2 /
CREATE OR REPLACE TYPE t1 AS OBJECT (c varchar(20));
*
ERROR at line 1:
ORA-02303: cannot drop or replace a type with type or table dependents
7.2.5 FORCEを指定した型の作成または置換
表の依存性を持つ型は置換できないため、型に表の依存性がある場合、CREATE
OR
REPLACE
FORCE
文は失敗します。
例7-9に、CREATE
OR
REPLACE
FORCE
文が型の依存性を持つ型の置換に続いて親の型を使用した表の作成に成功するコードを示します。ただし、最後のCREATE
OR
REPLACE
FORCE
文は、型に表の依存性があり、FORCE
オプションを使用しても表の依存性を持つ型は置換できないため、失敗します。
関連項目:
SQL文CREATE
OR REPLACE TYPE
の詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
例7-9 FORCEを指定したCREATE OR REPLACE
SQL> CREATE OR REPLACE TYPE t1 FORCE AS OBJECT (c varchar(20));
2 /
Type created.
SQL> CREATE TABLE tb1 (c1 t1);
Table created.
SQL> CREATE OR REPLACE TYPE t1 FORCE AS OBJECT (d number);
2 /
CREATE OR REPLACE TYPE
t1 FORCE AS OBJECT (d number);
*
ERROR at line 1:
ORA-22866: cannot replace a type with table dependents
7.2.6 代入可能な表および列の型依存性
特定の型の代入可能な表または列は、その型のみでなく型のすべてのサブタイプも依存します。
それは、型のサブタイプで追加されたそれぞれの属性について、非表示列が表に追加されることからもわかります。代入可能な表または列に、このサブタイプのデータが何も入っていない場合も、非表示列は追加されます。
例7-10では、型person_typ
のpersons
表は、person_typ
のみでなく、person_typ
のサブタイプであるstudent_typ
およびpart_time_student_typ
にも依存します。
依存型、表または列を持つサブタイプを削除しようとすると、DROP
TYPE
文はエラーを戻し、異常終了します。したがって、part_time_student_typ
は、persons
表に依存しているので、削除しようとすると、エラーとなります。
依存表または依存列が存在しても、削除する型のデータが何も入っていない場合は、VALIDATE
キーワードを使用して、型を削除できます。VALIDATE
キーワードが使用されていると、指定された型のインスタンスが実際に格納されているかどうかを調べ、何も見つからなければ、型を削除します。型に固有の属性と関連付けられた非表示列も削除されます。
例7-10で、part_time_student_typ
に依存表(persons
)があるため、最初のDROP
TYPE
文に失敗します。ただし、persons
にpart_time_student_typ
のインスタンスが何も入っていなければ(および他の依存表または依存列のいずれも入っていなければ)、VALIDATE
キーワードにより2番目のDROP
TYPE
文は正常に実行されます。
例7-10 VALIDATEを使用するおよび使用しないDROP TYPE
CREATE TYPE person_typ AS OBJECT ( idno NUMBER, name VARCHAR2(30), phone VARCHAR2(20)) NOT FINAL; / CREATE TYPE student_typ UNDER person_typ ( dept_id NUMBER, major VARCHAR2(30)) NOT FINAL; / CREATE TYPE part_time_student_typ UNDER student_typ (number_hours NUMBER); / CREATE TABLE persons OF person_typ; -- Following generates an error due to presence of Persons table DROP TYPE part_time_student_typ -- incorrect statement; -- Following succeeds if there are no stored instances of part_time_student_typ DROP TYPE part_time_student_typ VALIDATE;
注意:
サブタイプの削除中に、VALIDATE
オプションを使用することをお薦めします。
関連項目:
代入性の詳細な説明は、「型階層内の型の代入」を参照してください
7.2.7 DROP TYPE FORCEオプション
DROP
TYPE
文にはFORCE
オプションがあり、型に依存型または依存表がある場合でも、型が削除されます。
存在するすべての依存型または依存表に無効のマークが付けられ、型が削除されるとアクセス不能になるので、FORCE
オプションは慎重に使用します。この理由で無効のマークが付けられた表のデータに、再びアクセスすることはできません。こうした表に対して実行できる操作は、削除のみです。
関連項目:
型の変更方法の詳細は、「型進化」を参照してください。