Oracle PL/SQLオブジェクト型:CREATE TYPEの例
⚡ スマートサマリー
PL/SQLのオブジェクト型は、オブジェクト指向プログラミングを Oracleこれにより、属性とメソッドを用いて現実世界のエンティティをモデル化できます。コンストラクタ、継承、等価比較をサポートしているため、単一のスキーマレベルの型で構造化データを格納および処理できます。

PL/SQLのオブジェクト型とは何ですか?
オブジェクト指向プログラミングは、再利用可能なコンポーネントや複雑なアプリケーションの構築に特に適しています。プログラムは「アクション」ではなく「オブジェクト」を中心に構成されます。つまり、単一のアクションではなく、オブジェクト全体と連携して動作するように設計されています。このアプローチにより、プログラマーはオブジェクトエンティティレベルで詳細な設定や操作を行うことができます。
下の図は、銀行口座をオブジェクトエンティティとして扱うオブジェクトタイプの例を示しています。オブジェクト属性には値(銀行口座の場合は口座番号、残高など)が格納され、オブジェクトメソッドには金利の計算や銀行取引明細書の生成といった動作が記述されます。これらの動作はそれぞれ処理を完了する必要があります。
In PL / SQLのオブジェクト指向プログラミングは、オブジェクト型に基づいています。オブジェクト型は、現実世界のあらゆる実体を表すことができます。以下のセクションでは、オブジェクト型、その構成要素、そしてオブジェクトの作成方法と使用方法について解説します。
オブジェクトタイプのコンポーネント
PL/SQLオブジェクト型は主に2つの構成要素から成り立っています。
- Attributes
- メンバー/メソッド
Attributes
属性とは、データが格納される列またはフィールドのことです。各属性は、その属性の処理および格納タイプを定義するデータ型にマッピングされます。属性は、有効なデータ型であればどれでも構いません。 PL/SQLデータ型、または別のオブジェクト タイプである可能性があります。
メンバー/メソッド
メンバー、またはメソッドは サブプログラム オブジェクト型内部で定義されます。これらはデータを格納するために使用されるのではなく、オブジェクト型内部で実行される処理(例えば、オブジェクトにデータを格納する前にデータを検証する処理)を定義します。これらはオブジェクト型の仕様で宣言され、オブジェクト型の本体で定義されます。本体は省略可能です。メンバーが存在しない場合、オブジェクト型には本体がありません。
オブジェクトを作成する Oracle
オブジェクト型はサブルーチンレベルでは作成できません。スキーマレベルでのみ作成可能です。スキーマでオブジェクト型が定義されると、サブルーチンで使用できるようになります。オブジェクト型は「CREATE TYPE」文を使用して作成され、型本体はオブジェクト型が既に存在する場合にのみ作成できます。
以下のスクリーンショットは、オブジェクト仕様のためのCREATE TYPE構文と、そのメソッドを定義するCREATE TYPE BODY構文を示しています。
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
構文の説明:
- 上記の構文は、属性を持つオブジェクトと、メソッドを持つオブジェクト本体を作成する方法を示しています。
- メソッドはオブジェクト本体でオーバーロードすることもできます。
オブジェクト型の宣言初期化
PL/SQLの他のコンポーネントと同様に、オブジェクト型はプログラムで使用する前に宣言する必要があります。オブジェクト型が作成されると、サブルーチンの宣言セクションでそのオブジェクト型の変数を宣言するために使用できます。
変数がオブジェクト型として宣言されると、実行時にそのオブジェクト型の新しいインスタンスが作成され、この新しく作成されたインスタンスは変数名で参照されます。このようにして、単一のオブジェクト型が異なるインスタンスに複数の値を格納することができます。
以下のスクリーンショットは、変数がオブジェクト型として宣言されている様子を示しています。 PL/SQLブロック.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
構文の説明:
- 上記の構文は、 変数 宣言セクションにおけるオブジェクト型として。
サブルーチン内で変数がオブジェクト型として宣言されると、その変数はアトミックにヌルになります。つまり、オブジェクト全体がヌル状態です。プログラム内で使用するには、事前に値を初期化する必要があります。オブジェクトの初期化はコンストラクタを使用して行います。
コンストラクタは、オブジェクトの暗黙的なメソッドであり、オブジェクト型と同じ名前で参照できます。以下のスクリーンショットは、オブジェクト型インスタンスの初期化を示しています。
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
構文の説明:
- 上記の構文は、オブジェクト型インスタンスをnull値で初期化する方法を示しています。
- オブジェクト自体は初期化されるとnullではなくなりますが、オブジェクト内の属性は値が割り当てられるまでnullのままです。
コンストラクター
コンストラクタは、オブジェクトの暗黙的なメソッドであり、オブジェクト型と同じ名前で参照できます。オブジェクトが初めて参照されるたびに、このコンストラクタが暗黙的に呼び出されます。
これらのコンストラクタを使用してオブジェクトを初期化することもできます。コンストラクタは、オブジェクト型本体にオブジェクト型と同じ名前のメンバーを定義することで明示的に定義できます。
例1: 次の例では、オブジェクト型メンバーを使用して、emp テーブルに ('RRR', 1005, 20000, 1000) と ('PPP', 1006, 20000, 1001) の値を持つレコードを挿入します。データが挿入されたら、オブジェクト型メンバーを使用してデータを表示します。また、明示的なコンストラクタを使用して、2 番目のレコードのマネージャー ID にデフォルト値 1001 を設定します。
以下の手順で実行します。
- ステップ1:オブジェクト型とオブジェクト型本体を作成します。
- ステップ 2: emp_no 1005 の暗黙的コンストラクタを介してオブジェクト型を呼び出すための匿名ブロックを作成します。
- ステップ 3: emp_no 1006 の明示的なコンストラクタを介してオブジェクト型を呼び出すための匿名ブロックを作成します。
ステップ1)オブジェクト型とオブジェクト型本体を作成します。
以下のスクリーンショットは、emp_objectオブジェクト型の仕様が、その属性とメンバーとともに作成されている様子を示しています。
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
以下のスクリーンショットは、明示的なコンストラクタとメンバプロシージャを使用してemp_object型の本体が作成されている様子を示しています。
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line('Constructor fired..'); SELF.emp_no:=p_emp_no; SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.manager:=1001; RETURN; END; MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary:'||salary); Dbms_output.put_line('Manager:'||manager); END; END; /
Code 説明
- Code 1行目~9行目: 4つの属性と3つのメンバーを持つオブジェクト型「emp_object」を作成します。このオブジェクト型には、3つのパラメータのみを持つコンストラクタの定義が含まれています。(実際の暗黙的なコンストラクタは、オブジェクト型に存在する属性の数と同じ数のパラメータを持ちます。)
- Code 10行目: 型本体を作成しています。
- Code 11行目~21行目: 明示的なコンストラクタを定義します。パラメータ値を属性に割り当て、属性「manager」にデフォルト値「1001」を割り当てます。
- Code 22行目~26行目: 属性値が「emp」テーブルに挿入されるメンバー「insert_records」を定義します。
- Code 27行目~34行目: オブジェクトタイプの属性値を表示するメンバー「display_records」を定義します。
出力:
タイプが作成されました
型本体が作成されました
ステップ2) emp_no 1005 の暗黙的なコンストラクタを介して作成されたオブジェクト型を呼び出すための匿名ブロックを作成します。
以下のスクリーンショットは、暗黙的なコンストラクタを介してemp_objectを呼び出す匿名ブロックを示しています。
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,'RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Code 説明
- Code 37行目~45行目: 暗黙的なコンストラクタを使用してレコードを挿入します。コンストラクタの呼び出しには、属性値の実際の数が含まれます。
- Code 38行目: 'guru_emp_det' をオブジェクト型 'emp_object' として宣言します。
- Code 41行目: ステートメント「guru_emp_det.display_records」は「display_records」メンバーを呼び出し、属性値を表示します。
- Code 42行目: ステートメント「guru_emp_det.insert_records」は「insert_records」メンバーを呼び出し、属性値がテーブルに挿入されます。その後、ブロックは トランザクション.
出力:
従業員名: RRR
社員番号: 1005
給与:20000
マネージャー : 1000
ステップ3) emp_no 1006 の明示的なコンストラクタを介して作成されたオブジェクト型を呼び出すための匿名ブロックを作成します。
以下のスクリーンショットは、明示的なコンストラクタを介して3つの引数でemp_objectを呼び出す匿名ブロックを示しています。
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
出力
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Code 説明:
- Code 46行目~53行目: 明示的なコンストラクタを使用してレコードを挿入します。
- Code 46行目: 'guru_emp_det' をオブジェクト型 'emp_object' として宣言します。
- Code 50行目: ステートメント「guru_emp_det.display_records」は「display_records」メンバーを呼び出し、属性値を表示します。
- Code 51行目: ステートメント「guru_emp_det.insert_records」は「insert_records」メンバーを呼び出し、属性値がテーブルに挿入されます。引数は3つしか渡されないため、明示的なコンストラクタはマネージャーIDをデフォルト値の1001に設定します。
オブジェクト型の継承
継承プロパティにより、サブオブジェクト型はスーパーオブジェクト型(親オブジェクト型)のすべての属性とメンバーにアクセスできるようになります。
サブオブジェクト型は継承オブジェクト型、スーパーオブジェクト型は親オブジェクト型と呼ばれます。以下の構文は、親オブジェクト型と継承オブジェクト型を作成する方法を示しています。下のスクリーンショットは、親(SUPER)型の構文を「NOT FINAL」としてマークしたものです。
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
構文の説明:
- 上記の構文は、SUPER型の作成方法を示しています。NOT FINAL句により、その型を継承することが可能になります。
以下のスクリーンショットは、UNDERキーワードを使用して作成された継承型(SUB)の構文を示しています。
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
構文の説明:
- 上記の構文は、SUB型の作成方法を示しています。SUB型には、親オブジェクト型からすべてのメンバーと属性が含まれます。
例1: 以下の例では、継承プロパティを使用して、レコード ('RRR', 1007, 20000) にマネージャー ID '1002' のレコードを挿入します。プログラムは次の手順で実行します。
- ステップ1:SUPER型を作成します。
- ステップ2:SUB型とSUB本体を作成します。
- ステップ3:SUB型を呼び出すための匿名ブロックを作成します。
ステップ1)SUPER型または親型を作成します。
以下のスクリーンショットは、NOT FINAL句を使用してemp_objectスーパータイプが作成されている様子を示しています。
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Code 説明:
- Code 1行目~9行目: 4つの属性と3つのメンバーを持つオブジェクト型「emp_object」を作成します。このオブジェクト型には、3つのパラメータのみを持つコンストラクタの定義が含まれています。「NOT FINAL」として宣言されているため、親型です。
ステップ2)SUPER型の下にSUB型を作成します。
以下のスクリーンショットは、継承された型である sub_emp_object とその本体が作成されている様子を示しています。
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name,salary,manager); END; END; /
Code 説明:
- Code 10行目~13行目: 継承型として「sub_emp_object」を作成し、追加属性「default_manager」とメンバプロシージャ宣言を追加します。
- Code 14行目: 継承したオブジェクト型の本体を作成します。
- Code 16行目~21行目: マネージャー値を除くSUPERオブジェクト型の値を使用して「emp」テーブルにレコードを挿入するメンバプロシージャを定義します。マネージャー値には、SUB型の「default_manager」を使用します。
ステップ 3) SUB 型を呼び出すための匿名ブロックを作成します。
以下のスクリーンショットは、SUB型を呼び出し、デフォルトのマネージャーIDを挿入する匿名ブロックを示しています。
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Code 説明:
- Code 25行目: 'guru_emp_det' を 'sub_emp_object' 型として宣言します。
- Code 27行目: 暗黙的なコンストラクタを使用してオブジェクトを初期化します。コンストラクタには 5 つのパラメータ (PARENT 型の 4 つの属性と SUB 型の 1 つの属性) があります。最後のパラメータ (1002) は、default_manager 属性の値を定義します。
- Code 28行目: コンストラクタで渡されたデフォルトマネージャーIDを使用してレコードを挿入するために、メンバー「insert_default_mgr」を呼び出します。
PL/SQLオブジェクトの同等性
同じオブジェクト型に属するオブジェクトインスタンスは、等価性を比較できます。これを行うには、オブジェクト型にORDERメソッドと呼ばれる特別なメソッドが必要です。
この ORDER メソッドは、数値型を返す関数である必要があります。入力として 2 つのパラメータを受け取ります (1 番目のパラメータ: 自身オブジェクトインスタンスの ID、2 番目のパラメータ: 他のオブジェクトインスタンスの ID)。
2つのオブジェクトインスタンスのIDが比較され、その結果が数値として返されます。
- 正の値は、SELFオブジェクトのインスタンスが他のインスタンスよりも大きいことを示します。
- 負の値は、SELFオブジェクトインスタンスが他のインスタンスよりも小さいことを示します。
- ゼロは、SELFオブジェクトのインスタンスが他のインスタンスと等しいことを示します。
- どちらかのインスタンスがnullの場合、関数はnullを返します。
以下のスクリーンショットは、等価性チェックのために型本体に含める必要があるORDERメンバ関数の構文を示しています。
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>THEN RETURN -1; --any negative number will do ELSIF id>c.id THEN RETURN 1; --any positive number will do ELSE RETURN 0; END IF; END; . . ); /
構文の説明:
- 上記の構文は、等価性チェックのために型本体に含める必要があるORDER関数を示しています。
- この関数のパラメータは、同じオブジェクト タイプのインスタンスである必要があります。
- この関数は「obj_instance_1.match(obj_instance_2)」のように呼び出すことができ、この式は、obj_instance_1とobj_instance_2がオブジェクト型のインスタンスである場合に、表示されている数値を返します。
例1: 次の例では、2つのオブジェクトを比較します。2つのインスタンスを作成し、それらの「salary」属性を比較します。これは2つのステップで行います。
- ステップ1:オブジェクトの型と本体を作成します。
- ステップ2:オブジェクトインスタンスを比較するための匿名ブロックを作成します。
ステップ1)オブジェクトの型と本体を作成する。
以下のスクリーンショットは、emp_object_equality仕様とその本体を示しています。この仕様では、salary属性を比較するORDER関数が定義されています。
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF; END; END; /
Code 説明:
- Code 1行目~4行目: 属性1つとメンバー1つを持つオブジェクトタイプ「emp_object_equality」を作成します。
- Code 6行目~16行目: SELFインスタンスとパラメータインスタンスの「salary」属性を比較するORDER関数を定義します。SELFの給与が低い場合は負の値、高い場合は正の値、同じ場合は0を返します。
Code 出力:
タイプが作成されました
ステップ2)オブジェクトインスタンスを比較するための匿名ブロックを作成します。
以下のスクリーンショットは、給与に基づいて2つのemp_object_equalityインスタンスを比較する匿名ブロックを示しています。
DECLARE l_obj_1 emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_1:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equals(l_obj_2)>0 THEN Dbms_output.put_line('Salary of first instance is greater'); ELSIF l_obj_1.equals(l_obj_2)<0 THEN Dbms_output.put_line('Salary of second instance is greater'); ELSE Dbms_output.put_line('Salaries are equal'); END IF; END; /
出力
Salary of second instance is greater
Code 説明:
- Code 20行目: 'emp_object_equality'型のオブジェクト'l_obj_1'を宣言します。
- Code 21行目: 'emp_object_equality'型のオブジェクト'l_obj_2'を宣言します。
- Code 23行目: 'l_obj_1' を給与値 '15000' で初期化します。
- Code 24行目: 'l_obj_2' を給与値 '17000' で初期化します。
- Code 25行目~33行目: ORDER関数が返す数値に基づいてメッセージを印刷します。


















