277 UTL_REF
UTL_REFパッケージは、参照ベースの操作をサポートするためのPL/SQLプロシージャを提供します。SQLと異なり、UTL_REFプロシージャでは、オブジェクト表名が不明でも汎用タイプ・メソッドを書き込むことができます。
この章のトピックは、次のとおりです:
277.1 UTL_REFの概要
UTL_REFプロシージャでは、オブジェクト表名が不明でも汎用タイプ・メソッドを書き込むことができます。
Oracleは、ユーザー定義のコンポジット・タイプまたはオブジェクト・タイプをサポートします。オブジェクト・タイプのインスタンスをオブジェクトと呼びます。オブジェクト・タイプは、列のタイプとしてまたは表のタイプとして使用できます。
オブジェクト表では、表の各行にオブジェクトが格納されています。オブジェクト表にあるオブジェクトは、オブジェクト識別子で一意に識別できます。
参照はオブジェクトへの持続ポインタで、各参照にはオブジェクト識別子を含めることができます。参照は、オブジェクト・タイプの属性にしたり、表の列に格納することができます。参照を指定して、オブジェクトを取り出すことができます。
277.2 UTL_REFのセキュリティ・モデル
このパッケージを使用するには、プロシージャ・オプションが必要です。このパッケージは、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が実行されているクライアント・セッションの権限を使用して動作します。
277.3 UTL_REFのタイプ
オブジェクト・タイプは、ユーザーが定義するか、またはライブラリ・タイプとして提供されたコンポジット・データ・タイプです。
次の構文を使用して、オブジェクト・タイプ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;
277.4 UTL_REFの例外
UTL_REFファンクションの実行中に、様々な理由で例外が戻る場合があります。
-
選択したオブジェクトが存在しません。これには、次のいずれかの理由が考えられます。
-
オブジェクトは削除されたか、指定された参照先がありません(無効です)。
-
オブジェクト表は、削除されたか存在しません。
-
-
シリアル化可能トランザクションで、オブジェクトを変更またはロックできません。オブジェクトは、シリアル化可能トランザクションの開始後に、別のトランザクションで変更されました。
-
オブジェクトを選択または変更する権限がありません。
UTL_REFサブプログラムのコール元は、選択または変更するオブジェクトに対する適切な権限が必要です。
表277-1 UTL_REFの例外
| 例外 | 説明 |
|---|---|
|
|
権限が不十分です。 |
|
|
権限が不十分です。 |
|
|
シリアル化可能トランザクションの場合は、シリアル化できません。 |
|
|
デッドロックが検出されました。 |
|
|
データが見つかりません( |
UTL_REFパッケージは、名前の付いた例外を定義しません。特定の例外を捕捉して適切に処理するために、ブロックを処理する例外を定義できます。
277.5 UTL_REFサブプログラムの要約
この表は、UTL_REFサブプログラムを示し、簡単に説明しています。
表277-2 UTL_REFパッケージのサブプログラム
| サブプログラム | 説明 |
|---|---|
|
参照を指定してオブジェクトを削除します。 |
|
|
参照を指定してオブジェクトをロックします。 |
|
|
参照を指定してオブジェクトを選択します。 |
|
|
参照を指定してオブジェクトを更新します。 |
277.5.1 DELETE_OBJECTプロシージャ
このプロシージャは、参照を指定してオブジェクトを削除します。
このサブプログラムの意味は、次のSQL文に似ています。
DELETE FROM object_table WHERE REF(t) = reference;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。
構文
UTL_REF.DELETE_OBJECT ( reference IN REF "<typename>");
パラメータ
表277-3 DELETE_OBJECTプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
削除するオブジェクトの参照。 |
例外
発生する可能性があります。
例
この例は、次のシナリオを実行するための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);277.5.2 LOCK_OBJECTプロシージャ
このプロシージャは、参照を指定してオブジェクトをロックします。さらに、このプロシージャでは、プログラムによって、ロックされたオブジェクトを選択できます。
このサブプログラムの意味は、次の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>");
パラメータ
表277-4 LOCK_OBJECTプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
ロックするオブジェクトの参照。 |
|
|
ロックされたオブジェクトを格納するPL/SQL変数。この変数は、ロックされたオブジェクトと同じオブジェクト・タイプである必要があります。 |
例外
発生する可能性があります。
277.5.3 SELECT_OBJECTプロシージャ
このプロシージャは、参照を指定してオブジェクトを選択します。選択されたオブジェクトはデータベースから取り出され、その値はPL/SQLの変数'object'に入れられます。
このサブプログラムの意味は、次のSQL文に似ています。
SELECT VALUE(t) INTO object FROM object_table t WHERE REF(t) = reference;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。
構文
UTL_REF.SELECT_OBJECT ( reference IN REF "<typename>", object IN OUT "<typename>");
パラメータ
表277-5 SELECT_OBJECTプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
選択または取り出すオブジェクトへの参照。 |
|
|
選択したオブジェクトを格納するPL/SQL変数。この変数は、参照されたオブジェクトと同じオブジェクト・タイプである必要があります。 |
例外
発生する可能性があります。
277.5.4 UPDATE_OBJECTプロシージャ
このプロシージャは、参照を指定してオブジェクトを更新します。参照されたオブジェクトは、PL/SQL変数'object'に含まれている値で更新されます。
このサブプログラムの意味は、次のSQL文に似ています。
UPDATE object_table t SET VALUE(t) = object WHERE REF(t) = reference;
前述のSQL文と異なり、このサブプログラムでは、オブジェクトが常駐しているオブジェクト表名を指定する必要はありません。
構文
UTL_REF.UPDATE_OBJECT ( reference IN REF "<typename>", object IN "<typename>");
パラメータ
表277-6 UPDATE_OBJECTプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
更新するオブジェクトの参照。 |
|
|
オブジェクトの新規の値を含めるPL/SQL変数。この変数は、更新されたオブジェクトと同じオブジェクト・タイプである必要があります。 |
例外
発生する可能性があります。