UTL_REF
パッケージは、参照ベースの操作をサポートするためのPL/SQLプロシージャを提供します。SQLと異なり、UTL_REF
プロシージャでは、オブジェクト表名が不明でも汎用タイプ・メソッドを書き込むことができます。
この章では、次の項目について説明します。
概要
セキュリティ・モデル
タイプ
例外
Oracleは、ユーザー定義のコンポジット・タイプまたはオブジェクト・タイプをサポートします。オブジェクト・タイプのインスタンスをオブジェクトと呼びます。オブジェクト・タイプは、列のタイプとしてまたは表のタイプとして使用できます。
オブジェクト表では、表の各行にオブジェクトが格納されています。オブジェクト表にあるオブジェクトは、オブジェクト識別子で一意に識別できます。
参照はオブジェクトへの持続ポインタで、各参照にはオブジェクト識別子を含めることができます。参照は、オブジェクト・タイプの属性にしたり、表の列に格納することができます。参照を指定して、オブジェクトを取り出すことができます。
このパッケージを使用するには、プロシージャ・オプションが必要です。このパッケージは、SYS
(CONNECT /AS SYSDBA
)によって作成される必要があります。このパッケージが提供する操作は、パッケージ所有者SYS
ではなく、現行のコール・ユーザーのもとで実行されます。
UTL_REF
パッケージは、サーバー上のストアドPL/SQLプロシージャまたはパッケージとクライアント側のPL/SQLコードからも同様に使用できます。
サーバー上のPL/SQLプロシージャまたはパッケージから起動した場合、UTL_REF
は、REF
が指すオブジェクトに対する適切なアクセス権限が実行者にあることを検証します。
注意: これは、定義者の権限で操作する、サーバー上のPL/SQLパッケージまたはプロシージャとは対照的で、パッケージ所有者には、必要な操作を実行するための適切な権限が必要です。 |
したがって、UTL_REF
がユーザーのSYS
権限で定義された場合、ユーザーAが参照からオブジェクトを選択するためにUTL_REF
.SELECT
を起動すると、ユーザーA(実行者)は、権限をチェックする必要があります。
クライアント側のPL/SQLコードから起動した場合、UTL_REF
は、PL/SQLが実行されているクライアント・セッションの権限を使用して動作します。
オブジェクト・タイプは、ユーザーが定義するか、またはライブラリ・タイプとして提供されたコンポジット・データ・タイプです。次の構文を使用して、オブジェクト・タイプemployee_type
を作成できます。
CREATE TYPE employee_type AS OBJECT ( name VARCHAR2(20), id NUMBER, member function GET_ID (name VARCHAR2) RETURN MEMBER);
オブジェクト・タイプemployee_type
はユーザー定義タイプで、name
とid
の2つの属性およびメンバー・ファンクションのGET_ID
()が含まれています。
次のSQL構文を使用して、オブジェクト表を作成できます。
CREATE TABLE employee_table OF employee_type;
UTL_REF
ファンクションの実行中に、様々な理由で例外が戻る場合があります。たとえば、次の使用例では例外が発生します。
選択したオブジェクトが存在しません。これには、次のいずれかの理由が考えられます。
オブジェクトは削除されたか、指定された参照先がありません(無効です)。
オブジェクト表は、削除されたか存在しません。
シリアル化可能トランザクションで、オブジェクトを変更またはロックできません。オブジェクトは、シリアル化可能トランザクションの開始後に、別のトランザクションで変更されました。
オブジェクトを選択または変更する権限がありません。UTL_REF
サブプログラムのコール元は、選択または変更するオブジェクトに対する適切な権限が必要です。
表262-1 UTL_REFの例外
例外 | 説明 |
---|---|
|
権限が不十分です。 |
|
権限が不十分です。 |
|
シリアル化可能トランザクションの場合は、シリアル化できません。 |
|
デッドロックが検出されました。 |
|
データが見つかりません( |
UTL_REF
パッケージは、名前の付いた例外を定義しません。特定の例外を捕捉して適切に処理するために、ブロックを処理する例外を定義できます。
表262-2 UTL_REFパッケージのサブプログラム
サブプログラム | 説明 |
---|---|
|
参照を指定してオブジェクトを削除します。 |
|
参照を指定してオブジェクトをロックします。 |
|
参照を指定してオブジェクトを選択します。 |
|
参照を指定してオブジェクトを更新します。 |
このプロシージャは、参照を指定してオブジェクトを削除します。このサブプログラムの意味は、次のSQL文に似ています。
DELETE FROM object_table WHERE REF(t) = reference;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。
例
この例は、次のシナリオを実行するためのUTL_REF
パッケージの使用方法を示しています。会社の従業員が自宅住所の変更を上司に連絡するとします。
... Address_t
の宣言など...
CREATE OR REPLACE TYPE Person_t ( name VARCHAR2(64), gender CHAR(1), address Address_t, MEMBER PROCEDURE setAddress(addr IN Address_t) ); CREATE OR REPLACE TYPE BODY Person_t ( MEMBER PROCEDURE setAddress(addr IN Address_t) IS BEGIN address := addr; END; ); CREATE OR REPLACE TYPE Employee_t (
Person_t
で、REF
を使用したPerson_t
への継承の実装とsetAddress
の委任をシミュレーションします。
thePerson REF Person_t, empno NUMBER(5), deptREF Department_t, mgrREF Employee_t, reminders StringArray_t, MEMBER PROCEDURE setAddress(addr IN Address_t), MEMBER procedure addReminder(reminder VARCHAR2); ); CREATE TYPE BODY Employee_t ( MEMBER PROCEDURE setAddress(addr IN Address_t) IS myMgr Employee_t; meAsPerson Person_t; BEGIN
責任をthePerson
に委任して、アドレスを更新します。個人オブジェクトを参照からロックして、それをまた選択します。
UTL_REF.LOCK_OBJECT(thePerson, meAsPerson); meAsPerson.setAddress(addr);
thePerson
に委任します。
UTL_REF.UPDATE_OBJECT(thePerson, meAsPerson); if mgr is NOT NULL THEN
マネージャに覚書きを渡します。
UTL_REF.LOCK_OBJECT(mgr); UTL_REF.SELECT_OBJECT(mgr, myMgr); myMgr.addReminder ('Update address in the employee directory for' || thePerson.name || ', new address: ' || addr.asString); UTL_REF.UPDATE_OBJECT(mgr, myMgr); END IF; EXCEPTION WHEN OTHERS THEN errnum := SQLCODE; errmsg := SUBSTR(SQLERRM, 1, 200);
このプロシージャは、参照を指定してオブジェクトをロックします。さらに、このプロシージャでは、プログラムによって、ロックされたオブジェクトを選択できます。このサブプログラムの意味は、次のSQL文に似ています。
SELECT VALUE(t) INTO object FROM object_table t WHERE REF(t) = reference FOR UPDATE;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。オブジェクトの更新または削除前に、オブジェクトをロックする必要はありません。
構文
UTL_REF.LOCK_OBJECT ( reference IN REF "<typename>"); UTL_REF.LOCK_OBJECT ( reference IN REF "<typename>", object IN OUT "<typename>");
このプロシージャは、参照を指定してオブジェクトを選択します。選択されたオブジェクトはデータベースから取り出され、その値はPL/SQLの変数'object'に入れられます。このサブプログラムの意味は、次のSQL文に似ています。
SELECT VALUE(t) INTO object FROM object_table t WHERE REF(t) = reference;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。