2.4 オブジェクトに便利なファンクションおよび演算子
いくつかのファンクションや演算子は、オブジェクトやオブジェクトへの参照を扱う際に特に役に立ちます。
使用例は、このマニュアルの他の章でも示しています。
注意:
PL/SQLの場合、VALUE
、REF
およびDEREF
ファンクションが現れるのは、SQL文の中のみです。SQLファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
内容は次のとおりです。
2.4.1 CAST
CAST
は、ある組込みデータ型またはコレクション型の値を、別の組込みデータ型またはコレクション型の値に変換します。次に例を示します。
例2-33 CASTファンクションの使用
CREATE TYPE person_list_typ AS TABLE OF person_typ;/
SELECT CAST(COLLECT(contact) AS person_list_typ)
FROM contacts;
関連項目:
SQL CAST
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.2 CURSOR
CURSOR
式は、ネストしたカーソルを戻します。
CURSOR形式の式は、PL/SQLのREF
CURSOR
と同等で、REF
CURSOR
引数としてファンクションに渡すことが可能です。
関連項目:
SQL CURSOR
式の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.3 DEREF
SQL文のDEREF
ファンクションは、REF
に対応するオブジェクト・インスタンスを戻します。
DEREF
により戻されるオブジェクト・インスタンスは、REF
の宣言された型か、またはこの型のサブタイプになる可能性があります。
次に示す文は、表contact_ref
からperson_typ
オブジェクトを戻します。
例2-34 DEREFファンクションの使用
-- Using the DEREF Function example, not sample schema
SELECT DEREF(c.contact_ref), c.contact_date FROM contacts_ref c;
関連項目:
-
「REFの参照解除」
-
SQL
DEREF
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.4 IS OF type
IS
OF
type
の述語は、オブジェクト・インスタンスの型の特化レベルを検証します。
たとえば、次の問合せでは、person_obj_table
表に格納されている学生インスタンス(学生のすべてのサブタイプなど)がすべて取り出されます。
例2-35 IS OF type演算子を使用したサブタイプ値の問合せ
-- Using the IS OF type Operator to query Value of a subtype
SELECT VALUE(p) FROM person_obj_table p WHERE VALUE(p) IS OF (student_typ);
指定されたサブタイプではないオブジェクト、または指定されたサブタイプのサブタイプに対しては、IS
OF
よりFALSE
が戻されます。指定されたサブタイプのサブタイプは、指定されたサブタイプのさらに特化されたバージョンにすぎません。このようなサブタイプを除外するには、ONLY
キーワードが使用できます。このキーワードを使用すると、IS
OF
は指定された型を除くすべての型に対してFALSE
を戻します。
次に示す文は、個人、従業員および学生が入っているオブジェクト表person_obj_table
のオブジェクトを検証し、指定された2つの個人サブタイプであるemployee_typ
およびstudent_typ
(そのサブタイプが存在する場合は、これらのサブタイプも含まれます)のオブジェクトのみに対するREF
を戻します。
-- Using the IS OF type Operator to query for multiple subtypes
SELECT REF(p) FROM person_obj_table p WHERE VALUE(p) IS OF (employee_typ, student_typ);
次に、PL/SQLの同様の例を示します。個人が従業員または学生の場合、コードによって操作が実行されます。
-- Using the IS OF type Operator with PL/SQL
DECLARE var person_typ; BEGIN var := employee_typ(55, 'Jane Smith', '1-650-555-0144', 100, 'Jennifer Nelson'); IF var IS OF (employee_typ, student_typ) THEN DBMS_OUTPUT.PUT_LINE('Var is an employee_typ or student_typ object.'); ELSE DBMS_OUTPUT.PUT_LINE('Var is not an employee_typ or student_typ object.'); END IF; END; /
次の文は、最も狭い意味での型または特化された型がstudent_typ
である学生のみを戻します。表またはビューにstudent_typ
のサブタイプ(part_time_student_typ
など)のオブジェクトが含まれている場合、これらのオブジェクトは除外されます。この例は、TREAT
ファンクションを使用して、学生オブジェクトをビューの宣言された型person_typ
からstudent_typ
に変換します。
-- Using the IS OF type Operator to query for specific subtype only
SELECT TREAT(VALUE(p) AS student_typ) FROM person_obj_table p WHERE VALUE(p) IS OF(ONLY student_typ);
REF
が示すオブジェクトの型を検証する場合、IS
OF
type
の述語を使用して検証する前に、REF
の参照を解除するには、DEREF
ファンクションが使用できます。
たとえば、contact_ref
をREF
person_typ
として宣言すると、次に示すように学生についての行のみが取得できます。
-- Using the IS OF type Operator with DEREF
SELECT * FROM contacts_ref WHERE DEREF(contact_ref) IS OF (student_typ);
関連項目:
SQL IS
OF
type
条件の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.5 REF
SQL文のREF
ファンクションは、オブジェクト表またはビューの相関名(または表別名)を引数としてとり、その表またはビューからオブジェクト・インスタンスの参照(REF
)を戻します。
REF
ファンクションにより、表またはビューの宣言された型のオブジェクトの参照、またはその型のサブタイプのオブジェクトの参照が戻せます。たとえば、次の文は、idno
属性が12である学生や従業員の参照など個人全員の参照を戻します。
例2-36 REFファンクションの使用
-- Using the REF Function example, not sample schema
SELECT REF(p) FROM person_obj_table p WHERE p.idno = 12;
関連項目:
SQL REF
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.6 SYS_TYPEID
SYS_TYPEID
ファンクションを問合せで使用すると、引数として渡されたオブジェクト・インスタンスの最も狭い意味での型の型ID (非表示の型)が戻されます。
オブジェクト・インスタンスの最も狭い意味での型とは、インスタンスが属する型(つまり、ルート型から最も離れたインスタンスから取り出される型)です。たとえば、Timが定時制の学生だとすると、彼は学生であると同時に個人ですが、彼の最も狭い意味での型は定時制の学生です。
このファンクションは、代入可能なすべての列と対応付けられた非表示の型判別式の列から型IDを戻します。FINALのルート型についてはNULLの型IDを戻します。
この関数の構文は次のとおりです。
SYS_TYPEID(object_type_value)
SYS_TYPEID
ファンクションを使用するには、オブジェクト型の引数を付ける必要があります。非表示の型判別式の列について索引が作成できるようにすることが、このファンクションの主な目的です。
型階層に属するすべての型に、型階層内で一意な非NULL型IDが割り当てられます。型階層に属さない型には、NULL型IDが与えられます。
FINALのルート型を除くすべての型が、型階層に属します。FINALのルート型には、継承により関連付けられる型はありません。
-
これはFINALの型のため、そこから導出されるサブタイプを持つことはできません。
-
ルート型自身が他の型から導出されることはないため、ルート型のスーパータイプは存在しません。
SYS_TYPEID
の例として、person_typ
の代入可能なオブジェクト表person_obj_table
を検討してみましょう。person_typ
は、サブタイプとしてstudent_typ
を持ち、student_typ
のサブタイプとしてpart_time_student_typ
を持つ階層のルート型です。例2-20を参照してください。
次の問合せでは、SYS_TYPEID
を使用します。このファンクションは、person_obj_table
表の中にあるオブジェクト・インスタンスのname
属性およびtypeid
を取得します。インスタンスのそれぞれが、異なる型を持ちます。
例2-37 SYS_TYPEIDファンクションの使用
-- Using the SYS_TYPEID Function example, not sample schema
SELECT name, SYS_TYPEID(VALUE(p)) typeid FROM person_obj_table p;
関連項目:
-
型判別式の列およびその他の非表示列の詳細は、「代入可能な列およびオブジェクト表の非表示列」を参照してください。
-
SQL
SYS
TYPEID
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.7 TABLE()
テーブル・ファンクションとは、物理データベース表のように問い合せたり、PL/SQLのコレクション変数に割り当てることが可能な、行、ネストした表またはVARRAYのコレクションを生成するファンクションです。
テーブル・ファンクションは、問合せのFROM
句でデータベース表の名前のように使用したり、問合せのSELECT
リストで列名のように使用できます。
テーブル・ファンクションは、行のコレクションを入力として取ることができます。入力コレクション・パラメータには、VARRAY
やPL/SQL表のようなコレクション型か、またはREF
CURSOR
を使用できます。
Oracle Databaseによりテーブル・ファンクションの結果が繰り返し戻されるようにするには、PIPELINED
を使用します。テーブル・ファンクションにより、ネストした表またはVARRAY型が戻されます。問合せのFROM
句のファンクション名の前にTABLE
キーワードを使用して、テーブル・ファンクションを問い合せます。
2.4.8 TREAT
TREAT
ファンクションは、階層内の指定された異なる型(通常は、式の宣言された型のサブタイプ)として、特定の式を操作できるかを、実行時にチェックします。
つまり、TREAT
ファンクションは、スーパータイプのインスタンスをサブタイプのインスタンスとして扱おうとします(たとえば、個人を学生として扱います)。その人が学生であれば、学生が持つ可能性のある別の属性やメソッドと一緒に、学生として戻されます。その人が学生でない場合、TREAT
はSQLでNULL
を戻します。
TREAT
は、主に次の2つの目的で使用します。
-
ナローイング代入で、階層内のさらに特化された型の変数に式が代入できるように、式のタイプを変更するため(スーパータイプの値をサブタイプに設定するため)。
-
行または列の宣言された型のサブタイプの属性またはメソッドにアクセスするため。
型
T
の代入可能なオブジェクト表または列には、T
のすべてのサブタイプのすべての属性についての非表示列があります。これらの非表示列にはサブタイプの属性データが含まれますが、DESCRIBE
文でこれらの非表示列をリストすることはできません。TREAT
を使用すると、これらの列にアクセスできます。
2.4.8.1 ナローイング代入でのTREATの使用
ナローイング代入(スーパータイプの値をサブタイプに設定する代入)では、TREAT
ファンクションを使用します。ワイドニング代入との違いは、「型をまたがる代入」を参照してください。
例2-38では、TREAT
により、すべてのstudent_typ
インスタンス(のみ)が、person_typ
型(student_typ
のスーパータイプ)のperson_obj_table
から戻されます。この文は、TREAT
を使用して、p
の型をperson_typ
からstudent_typ
に変更します。
例2-38 問合せで特定のサブタイプを戻すためのTREATファンクションの使用
-- Using the TREAT Function to Return a Specific Subtype in a Query example,
-- not sample schema
SELECT TREAT(VALUE(p) AS student_typ) FROM person_obj_table p;
それぞれのp
についてTREAT
による変更が成功するのは、p
の値の最も狭い意味での型または特化された型がstudent_typ
か、そのサブタイプの1つである場合のみです。p
が学生でない個人の場合、またはp
がNULL
の場合、TREAT
はSQLではNULL
を戻し、PL/SQLでは例外を発行します。
REF
式の宣言された型を変更する場合にも、TREAT
が使用できます。次に例を示します。
-- Using the TREAT Function to modify declared type of a REF example,
-- not sample schema
SELECT TREAT(REF(p) AS REF student_typ) FROM person_obj_table p;
この例は、すべてのstudent_typ
インスタンスに対してREF
を戻します。学生ではない個人インスタンスについては、SQLの場合はNULL
REF
が戻され、PL/SQLの場合は例外が発行されます。
2.4.8.2 サブタイプの属性またはメソッドにアクセスするためのTREATファンクションの使用
行または列の宣言された型のサブタイプの属性またはメソッドにアクセスするために使用するのが、おそらくTREAT
の最も重要な使用方法です。次の問合せでは、major
属性を持つ個人、学生および定時制の学生全員のこの属性が取り出されます。学生ではない人については、NULL
が戻されます。
例2-39 特定のサブタイプの属性にアクセスするためのTREATファンクションの使用
SELECT name, TREAT(VALUE(p) AS student_typ).major major FROM person_obj_table p;
major
はstudent_typ
の属性であっても、表persons
の宣言された型であるperson_typ
ではないため、次の問合せは意図したとおりには機能しません。
SELECT name, VALUE(p).major major FROM person_obj_table p -- incorrect;
次に、PL/SQLの例を示します。
DECLARE var person_typ; BEGIN var := employee_typ(55, 'Jane Smith', '1-650-555-0144', 100, 'Jennifer Nelson'); DBMS_OUTPUT.PUT_LINE(TREAT(var AS employee_typ).mgr); END; /
関連項目:
SQL TREAT
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
2.4.9 VALUE
SQL文では、VALUE
ファンクションはオブジェクト表またはオブジェクト・ビューの相関変数(表の別名)を引数としてとり、表またはビューの行に対応するオブジェクト・インスタンスを戻します。
VALUE
ファンクションにより、行の宣言された型のインスタンスか、またはその型のサブタイプを戻すことができます。
例2-40では、最初にpart_time_student_typ
を作成し、次に学生や従業員を含む個人全員がperson_typ
の表person_obj_table
から戻されるSELECT
問合せを示しています。
例2-40 VALUEファンクションの使用
-- Requires Ex. 2-31 and 2-32 CREATE TYPE part_time_student_typ UNDER student_typ ( number_hours NUMBER); / SELECT VALUE(p) FROM person_obj_table p;
定時制の学生のみ、つまり最も狭い意味での型がpart_time_student_typ
であるインスタンスを取り出すには、ONLY
キーワードを使用して選択範囲を限定します。
SELECT VALUE(p) FROM person_obj_table p WHERE VALUE(p) IS OF (ONLY part_time_student_typ);
次の例では、オブジェクト表内のオブジェクト・インスタンスを更新するためにVALUE
が使用されています。
UPDATE person_obj_table p SET VALUE(p) = person_typ(12, 'Bob Jones', '1-650-555-0130') WHERE p.idno = 12;
関連項目:
-
SQL
VALUE
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。