ヘッダーをスキップ

Oracle Database 概要
11gリリース1(11.1)

E05765-03
目次
目次
索引
索引

戻る 次へ

6 スキーマ・オブジェクトの依存性

オブジェクトAの定義がオブジェクトBを参照している場合、AはBに依存します。この章では、スキーマ・オブジェクトの相互間の依存性と、Oracle Databaseがそのような依存性を自動的に追跡し管理する方法について説明します。こうした自動依存性管理により、AによってBの古いバージョンが使用されることがなく、Bの変更後にAを明示的に再コンパイルする必要もほとんどなくなります。

この項の内容は、次のとおりです。

スキーマ・オブジェクトの依存性の概要

スキーマ・オブジェクトのタイプによっては、定義の中で他のオブジェクトを参照できるものがあります。たとえば、ビューは表や他のビューを参照する問合せによって定義され、サブプログラムの本体の中には、他のオブジェクトを参照するSQL文を含めることができます。オブジェクトAの定義がオブジェクトBを参照している場合、Aは(Bに関する)依存オブジェクト、Bは(Aに関する)参照オブジェクトです。

次の問合せでは、現在のデータベース内で他のオブジェクトに依存するオブジェクトのタイプが示されます。

SELECT DISTINCT TYPE
  FROM DBA_DEPENDENCIES
     [ORDER BY TYPE]

次の問合せでは、現在のデータベース内で他のオブジェクトから参照されるオブジェクトのタイプが示されます。

SELECT DISTINCT REFERENCED_TYPE
  FROM DBA_DEPENDENCIES
    [ORDER BY REFERENCED_TYPE]

例6-1のSQL*Plusスクリプトは、前述の2つの問合せによる出力を示しています。

例6-1    依存オブジェクト・タイプと参照オブジェクト・タイプの表示

SQL> SELECT DISTINCT TYPE
  2    FROM DBA_DEPENDENCIES
  3      ORDER BY TYPE;

TYPE
------------------
DIMENSION
EVALUATION CONTXT
FUNCTION
INDEX
INDEXTYPE
JAVA CLASS
JAVA DATA
MATERIALIZED VIEW
OPERATOR
PACKAGE
PACKAGE BODY
PROCEDURE
RULE
RULE SET
SYNONYM
TABLE
TRIGGER
TYPE
TYPE BODY
UNDEFINED
VIEW
XML SCHEMA

22 rows selected.

SQL> SELECT DISTINCT REFERENCED_TYPE
  2    FROM DBA_DEPENDENCIES
  3      ORDER BY REFERENCED_TYPE;

REFERENCED_TYPE
------------------
EVALUATION CONTXT
FUNCTION
INDEXTYPE
JAVA CLASS
LIBRARY
NON-EXISTENT
OPERATOR
PACKAGE
PROCEDURE
SEQUENCE
SYNONYM
TABLE
TYPE
VIEW
XML SCHEMA

15 rows selected.

SQL>

参照オブジェクトの定義を変更した場合、その変更の内容によって、依存オブジェクトがエラーなしで機能し続ける場合と、そうでない場合があります。たとえば、表を削除した場合、その表に基づくビューは使用できなくなります。

一部の依存性のみを無効にするスキーマ・オブジェクトの変更例として、例6-2に示す2つのビューを考えます。このビューは、HR.EMPLOYEES表を基にしたものです。

EMPLOYEES表のEMAIL列を延長するよう指定するとします。この表を次のように変更します。

ALTER TABLE employees MODIFY email VARCHAR2(100);

COMMISSIONEDビューは、その選択リストにEMAILが含まれていないため、無効化されません。一方SIXFIGURESビューは、表内のすべての列が選択されているため、無効化の対象となります。

select object_name, status from user_objects where object_type = 'VIEW';
 
OBJECT_NAME          STATUS
-------------------- -------
COMMISSIONED         VALID
SIXFIGURES           INVALID

例6-2    一部の依存性を無効化するスキーマ・オブジェクトの変更

CREATE VIEW commissioned AS SELECT first_name, last_name, commission_pct FROM employees WHERE commission_pct > 0.00; CREATE VIEW sixfigures AS SELECT * FROM employees WHERE salary >= 100000; select object_name, status from user_objects where object_type = 'VIEW'; OBJECT_NAME STATUS -------------------- ------- COMMISSIONED VALID SIXFIGURES VALID

ビューは、その問合せ内で参照されているすべてのオブジェクトに依存します。例6-3に示したoc_inventoriesビューは、オブジェクト型inventory_typ、ファンクションwarehouse_typ、表inventoriesおよびwarehouseに依存しています。

例6-3    複数のオブジェクトに依存するビュー

CREATE TYPE inventory_typ
  OID '82A4AF6A4CD4656DE034080020E0EE3D'
  AS OBJECT
    ( product_id          NUMBER(6)
    , warehouse           warehouse_typ
    , quantity_on_hand    NUMBER(8)
    ) ;
/
CREATE OR REPLACE VIEW oc_inventories OF inventory_typ
  WITH OBJECT OID (product_id)
  AS SELECT i.product_id,
            warehouse_typ(w.warehouse_id, w.warehouse_name, w.location_id),
            i.quantity_on_hand
     FROM inventories i, warehouses w
     WHERE i.warehouse_id=w.warehouse_id;


注意

  • CREATE文を実行すると、すべての依存性が自動的に更新されます。

  • 動的SQL文では、依存性は作成されません。たとえば次の文を実行しても、tab1に対する依存性は作成されません。

    EXECUTE IMMEDIATE 'SELECT * FROM tab1 ...'
    
 

オブジェクト依存性の問合せ

静的データ・ディクショナリ・ビューUSER_DEPENDENCIESALL_DEPENDENCIESおよびDBA_DEPENDENCIESには、データベース・オブジェクト間の依存性が表示されます。

utldtree.sql SQLスクリプトを実行すると、オブジェクト依存性ツリーに関する情報が表示されるビューDEPTREE、ビューIDEPTREEおよびあらかじめソートされ整形表示されるDEPTREEが作成されます。

関連項目

DEPTREEIDEPTREEおよびutldtree.sqlスクリプトの詳細は、『Oracle Databaseリファレンス』を参照してください。 

オブジェクトのステータス

各データベース・オブジェクトには、表6-1に示されているいずれかのステータス値が割り当てられています。

表6-1    データベース・オブジェクトのステータス 
ステータス  意味 

有効 

データ・ディクショナリ内の現在の定義を使用して正常にコンパイルされた。 

コンパイル・エラー 

直前のコンパイル実行中にエラーが発生した。 

無効 

参照先のオブジェクトが変更されたために無効のマークが付けられている。(無効になるのは依存オブジェクトのみ。) 

権限取消し 

参照オブジェクトに対するアクセス権限が取り消された。(権限取消しの対象となるのは依存オブジェクトのみ。) 


注意

静的データ・ディクショナリ・ビューUSER_OBJECTSALL_OBJECTSおよびDBA_OBJECTSでは、「コンパイル・エラー」、「無効」、「権限取消し」はすべて同じものとみなされ、INVALIDと表示されます。 


依存オブジェクトの無効化

オブジェクトAがオブジェクトBに、オブジェクトBがオブジェクトCにそれぞれ依存している場合、A、Bはそれぞれ、B、Cへの直接依存性を持ち、AはCへの間接依存性を持ちます。

直接依存性は、それ自体に影響を与える変更(参照オブジェクトのシグネチャに対する変更)を参照オブジェクトに対して加えた場合にのみ無効になります。

間接依存性は、それ自体に影響を与えない変更を参照オブジェクトに対して加えることにより無効にできます。たとえば、Cを変更したことによりBが無効になると、A(およびBへの直接依存性と間接依存性のすべて)も無効になります。これを連鎖的な無効化と呼びます。

表6-2は、各オブジェクトに対して、それが依存する他のオブジェクトに変更があった場合どのような影響があるかを示したものです。

表6-2    オブジェクト・ステータスに影響を与える操作 
操作  影響のあった依存オブジェクトのステータス 

ALTER TABLE table ADD column 

次の場合はINVALID

  • 依存オブジェクト(ビューを除く)で、tableSELECT *が使用された場合。

  • 依存オブジェクトで、table%rowtypeが使用された場合。

  • 依存オブジェクトで、列リストを指定することなくtableに対してINSERTが実行された場合。

  • 依存オブジェクトが、SQLの結合が含まれる問合せ内のtableを参照している場合。

  • 依存オブジェクトが、PL/SQL変数を参照する問合せ内のtableを参照している場合。

これ以外の場合は変更なし。 

ALTER TABLE table {MODIFY|RENAME|DROP|SET UNUSED} column

ALTER TABLE table DROP CONSTRAINT not_null_constraint 

次の場合はINVALID

  • 依存オブジェクトがcolumnを直接参照している場合。

  • 依存オブジェクトで、tableSELECT *が使用された場合。

  • 依存オブジェクトで、table%rowtypeが使用された場合。

  • 依存オブジェクトで、列リストを指定することなくtableに対してINSERTが実行された場合。

これ以外の場合は変更なし。 

CREATE OR REPLACE VIEW view

オンライン表再定義(DBMS_REDEFINITION) 

新しい定義の列リストと以前の定義の列リストが異なり、少なくとも次の1つに該当する場合はINVALID

  • 依存オブジェクトが、ビューまたは表の新しい定義の中で修正または削除された列を参照している場合。

  • 依存オブジェクトで、view%rowtypeまたはtable%rowtypeが使用されている場合。

  • 依存オブジェクトで、列リストを指定することなくビューまたは表に対してINSERTが実行された場合。

  • ビューの新しい定義に新しい列が追加され、かつSQLの結合が含まれている問合せ内のビューまたは表を依存オブジェクトが参照している場合。

  • ビューの新しい定義に新しい列が追加され、PL/SQLを参照する問合せ内のビューまたは表を依存オブジェクトが参照している場合。

  • 依存オブジェクトが、RELIES ON句の中のビューまたは表を参照している場合。

これ以外の場合は変更なし。 

CREATE OR REPLACE SYNONYM synonym 

次の場合はINVALID

  • 新旧のsynonymのターゲットが異なり、かつ一方が表ではない場合。

  • synonymの新旧のターゲットがどちらも表で、かつその2つの表の列リストまたは付与権限が異なる場合。

  • synonymの新旧のターゲットがどちらも表で、かつ依存オブジェクトがビューであり、そのビューが参照している列が以前のターゲットの一意索引には関与し、新しいターゲットの一意索引には関与していない場合。

これ以外の場合は変更なし。 

RENAME {TABLE|VIEW|SEQUENCE|SYNONYM} 

INVALID 

DROP INDEX 

次の場合、索引が構築されている表の依存性はINVALID

  • 索引がファンクション索引であり、かつ依存オブジェクトがトリガーである場合。

  • 索引が一意索引であり、依存オブジェクトがビューであって、かつそのビューが、一意索引に関与している列を参照している場合。

 

DROP object 

INVALID 

CREATE OR REPLACE {PROCEDURE|FUNCTION} 

コール・シグネチャが変更された場合はINVALID。コール・シグネチャとは、パラメータ・リスト(パラメータの順序、名前および型)、戻り型、純粋度1、決定性、並列度、パイプライン処理および(プロシージャまたはファンクションがCまたはJavaで実装されている場合は)実装の各プロパティを指します。

プロシージャ本体やファンクション本体への変更など、これ以外の変更に対しては有効。 

CREATE OR REPLACE PACKAGE 

次の場合はINVALID

  • 依存オブジェクトが、削除または名前変更されたパッケージ項目を参照している場合。

  • 依存オブジェクトが参照しているパッケージ・プロシージャまたはパッケージ・ファンクションのコール・シグネチャまたはエントリ・ポイント番号2が変更された場合。

    参照されているプロシージャまたはファンクションにオーバーロードの候補が複数ある場合、それらの候補のコール・シグネチャまたはエントリ・ポイント番号が変更されるか、候補が追加または削除されると、依存オブジェクトは無効。

  • 依存オブジェクトが参照しているパッケージ・カーソルのコール・シグネチャ、行タイプまたはエントリ・ポイント番号が変更された場合。

  • 依存オブジェクトが参照しているパッケージ・タイプまたはパッケージ・サブタイプの定義が変更された場合。

  • 依存オブジェクトが参照しているパッケージの変数または定数の名前、データ型、初期値、オフセット番号のいずれかが変更された場合。

  • パッケージ純粋度1が変更された場合。

これ以外の場合は変更なし。 

CREATE OR REPLACE PACKAGE BODY 

変更なし。 

REVOKE DML-object-privilege3 ON object FROM user 

objectに依存しているuserのオブジェクトはすべてINVALID4 

REVOKE DML-object-privilege3 ON object FROM PUBLIC 

objectに依存しているデータベース内のオブジェクトはすべてINVALID4 

1 純粋度とは、SQL問合せ内部でPL/SQLファンクションを起動する際に不測の影響(予期せぬデータ変更など)が生じるのを回避するための一連のルールです。パッケージ純粋度とは、パッケージ初期化ブロック内のコードの純粋度を指します。

2 プロシージャやファンクションのエントリ・ポイント番号は、PL/SQLパッケージ・コードにおける位置によって決まります。PL/SQLパッケージの最後に追加されたプロシージャやファンクションには、新しいエントリ・ポイント番号が付与されます。

3 DMLオブジェクト権限は、SELECT、INSERT、UPDATE、DELETEおよびEXECUTEです。

4 再有効化する場合には、再コンパイルする必要はありません。詳細は、「無効なPL/SQLオブジェクトの即時再有効化」を参照してください。

この項の内容は、次のとおりです。

セッションの状態と参照パッケージ

パッケージ構成を参照するセッションごとに、各パッケージの独自のインスタンスが存在します。このインスタンスには、パブリック変数とプライベート変数、カーソルおよび定数の永続的な状態が含まれます。その後、セッションのインスタンス化されたパッケージのいずれかが無効になった後、再度有効化されると、そのセッションのパッケージのインスタンス化は、状態も含めてすべて失われる可能性があります。

セキュリティ認可

ユーザーやPUBLICに対してDMLオブジェクト権限やシステム権限の付与または取消しが実行されたことを検知すると、Oracle Databaseはその所有者のすべての依存オブジェクトを自動的に無効にします。Oracle Databaseは依存オブジェクトを無効にして、その依存オブジェクトの所有者が参照オブジェクトに対する必要な権限を引き続き持っていることを検証します。

無効化を回避するためのガイドライン

依存オブジェクトの無効化を回避するには、次のガイドラインに従ってください。

パッケージ最後尾への新しい項目の追加

パッケージに新しい項目を追加する場合、その項目はパッケージの最後尾に追加します。これにより、パッケージの最上位にある既存項目は、エントリ・ポイント番号が維持され、無効になることはありません。

たとえば、次のパッケージを考えてみます。

CREATE OR REPLACE PACKAGE pkg1 IS
  FUNCTION get_var RETURN VARCHAR2;
END;

次のようにpkg1の最後尾に項目を追加した場合、get_varファンクションを参照する依存性が無効になることはありません。

CREATE OR REPLACE PACKAGE pkg1 IS
  FUNCTION get_var RETURN VARCHAR2;
  PROCEDURE set_var (v VARCHAR2);
END;

次のようにget_varファンクションとset_varプロシージャの間に項目を挿入すると、set_varファンクションを参照する依存性は無効になります。

CREATE OR REPLACE PACKAGE pkg1 IS
  FUNCTION get_var RETURN VARCHAR2;
  PROCEDURE assert_var (v VARCHAR2);
  PROCEDURE set_var (v VARCHAR2);
END;

ビューによる各表の参照

ビューを使用して表を間接的に参照します。これにより、次のような操作が可能となります。

CREATE OR REPLACE VIEWを実行した場合、新しいROWTYPEと以前のROWTYPEが一致していれば、既存のビューまたはその依存性が無効になることはありません。

オブジェクトの再有効化

有効でないオブジェクトを参照する場合は、そのオブジェクトが有効化され使用可能な状態になる必要があります。オブジェクトは、参照された時点で自動的に有効になるため、ユーザーがなんらかの操作を明示的に行う必要はありません。

有効でないオブジェクトは、コンパイル・エラー、権限取消し、無効のいずれかのステータスを持ちます。これらの用語の定義は、表6-1を参照してください。

この項の内容は、次のとおりです。

コンパイル時にエラーが発生したオブジェクトの再有効化

コンパイル中にエラーが発生したオブジェクトは、コンパイラで自動的に再有効化することはできません。こうしたオブジェクトは、コンパイラにより再コンパイルされ、エラーが発生しなければ再有効化されます。エラーが発生した場合は無効のままです。

権限が取り消されたオブジェクトの再有効化

コンパイラでは、権限が取り消されたオブジェクトに対して、その参照オブジェクトすべてに対するアクセス権限があるかどうかのチェックが行われます。アクセス権限がある場合は、権限が取り消されたオブジェクトは、再コンパイルされることなく再有効化されます。アクセス権限がない場合は、それを示すエラー・メッセージがコンパイラにより表示されます。

無効なSQLオブジェクトの再有効化

SQLコンパイラでは、無効なオブジェクトの再コンパイルが行われます。オブジェクトは、再コンパイル中にエラーが発生しなければ再有効化されます。エラーが発生した場合は無効のままです。

無効なPL/SQLオブジェクトの再有効化

PL/SQLコンパイラでは、無効なPL/SQLプログラム・ユニット(プロシージャ、ファンクションまたはパッケージ)について、それ自体に影響を与えるような変更が参照オブジェクトに対して加えられているかどうかのチェックが行われます。変更されている場合、コンパイラでは無効なオブジェクトの再コンパイルが行われます。オブジェクトは、再コンパイル中にエラーが発生しなければ再有効化されます。エラーが発生した場合は無効のままです。変更されていなければ、無効なオブジェクトは再コンパイルされることなく再有効化されます。「無効なPL/SQLオブジェクトの即時再有効化」を参照してください。

無効なPL/SQLオブジェクトの即時再有効化

PL/SQLコンパイラでは、無効なPL/SQLプログラム・ユニット(プロシージャ、ファンクションまたはパッケージ)について、それ自体に影響を与えるような変更が参照オブジェクトに対して加えられているかどうかのチェックが行われます。変更されていなければ、無効なオブジェクトは再コンパイルされることなく再有効化されます。連鎖的な無効化により無効になったオブジェクトの再有効化は通常、即時に行われます。

たとえば、次の表、パッケージおよびプロシージャを考えてみます。

CREATE TABLE tab1(n NUMBER);

CREATE OR REPLACE PACKAGE pkg1 IS
  TYPE rec1 IS tab1%ROWTYPE;  -- pkg1 depends on tab1
  PROCEDURE p(n NUMBER);
END pkg1;

CREATE OR REPLACE PROCEDURE proc1 IS
BEGIN
  pkg1.p(5);  -- proc1 depends on pkg1
END proc1;

次の文を実行すると、pkg1tab1に依存)が無効になります。これにより、proc1pkg1に依存)も連鎖的に無効となります。

ALTER TABLE tab1 ADD(v VARCHAR2(20));

ただし、pkg1.pのシグネチャは変更されていないため、PL/SQLコンパイラでは、proc1を再コンパイルすることなく再度有効にすることができます。

スキーマの範囲内での名前解決

SQL文で参照されているオブジェクトの名前は、1つ以上の要素で構成されています。各構成要素は、ピリオドで区切られます(例: hr.employees.department_id)。

Oracle Databaseでは、次の手順に従ってオブジェクト名の解決が実行されます。

  1. オブジェクト名の先頭の要素を修飾します。

    オブジェクト名に要素が1つしかない場合は、その要素が最初の要素となります。要素が2つ以上ある場合は、最も左にあるピリオドの左側の要素が先頭の要素です。たとえば、hr.employees.department_idでは、hrが先頭の要素です。

    先頭の要素を修飾する手順は次のとおりです。

    1. オブジェクト名が、SELECT文のFROM句に含まれる表名であり、かつ2つ以上の構成要素を持つ場合は、手順dに進みます。それ以外の場合は、手順bに進みます。

    2. 現在のスキーマ内で、最初の要素と一致する名前を持つオブジェクトが検索されます。

      見つかった場合は、手順2に進みます。それ以外の場合は、手順cに進みます。

    3. 最初の要素と一致するパブリック・シノニムが検索されます。

      見つかった場合は、手順2に進みます。それ以外の場合は、手順dに進みます。

    4. 最初の要素と名前が一致するスキーマが検索されます。

      該当するスキーマが見つかった場合、オブジェクト名に後続の要素があれば、手順eに進みます。それ以外の場合は、エラーが戻され、オブジェクト名を修飾できません。

    5. 手順dで見つかったスキーマ内で、オブジェクト名の2番目の要素と一致する名前を持つ組込みファンクションが検索されます。

      該当する組込みファンクションが見つかった場合は、スキーマによりその組込みファンクションが再定義されています。オフジェクト名は、スキーマによって定義された同名のファンクションではなく、元の組込みファンクションに解決されます。手順2に進みます。

      該当する組込みファンクションが見つからなかった場合は、エラーが戻され、オブジェクト名を修飾できません。

  2. スキーマ・オブジェクトは修飾されています。オブジェクト名の残りの要素は、このスキーマ・オブジェクトの有効な部分と一致する必要があります。

    たとえば、オブジェクト名がhr.employees.department_idである場合、hrがスキーマとして修飾されます。employeesが表として修飾されている場合、department_idはその表の列に対応する必要があります。また、employeesがパッケージとして修飾されている場合、department_idはそのパッケージのパブリック定数、変数、プロシージャまたはファンクションに対応する必要があります。

Oracle Databaseによる参照の解決では、オブジェクトは、他のオブジェクトが存在しないという事実に依存する場合があります。このような状況が発生するのは、依存オブジェクトで使用されている参照の解釈が、別のオブジェクトの存在により多義的になる場合です。

関連項目

詳細は、『Oracle Database管理者ガイド』を参照してください。 

ローカル依存性の管理

ローカル依存性の管理が行われるのは、Oracle Databaseにおいて、単一データベース内のオブジェクト間で依存性が管理される場合です。たとえば、プロシージャ内の文が、同じデータベース内の表を参照する場合があります。

リモート依存性の管理

リモート依存性の管理が行われるのは、Oracle Databaseにおいて、ネットワークを介した分散環境で依存性が管理される場合です。たとえば、Oracle Formsトリガーは、データベース内のスキーマ・オブジェクトに依存する場合があります。また、分散データベースにおいて、ローカル・ビューの定義問合せがリモート表を参照する場合があります。

Oracle Databaseでは、分散データベースの依存性の管理も行われます。たとえば、Oracle Formsアプリケーション内のトリガーが表を参照する場合があります。データベース・システムでは、このようなオブジェクト間の依存性を管理する必要があります。Oracle Databaseでは、関係するオブジェクトの種類によっては、リモート依存性を管理するために別のメカニズムが使用されます。

この項の内容は、次のとおりです。

ローカルおよびリモートのデータベース・プロシージャ間の依存性

ファンクション、パッケージ、トリガーなど、ストアド・プロシージャの相互間の依存性は、分散データベース・システムにおいてはタイムスタンプのチェックまたはシグネチャのチェックを使用して管理されます(「タイムスタンプのチェック」および「シグネチャのチェック」を参照してください)。

タイムスタンプとシグネチャのどちらでリモート依存性を管理するかについては、動的初期化パラメータREMOTE_DEPENDENCIES_MODEで指定します。

関連項目

『Oracle Database PL/SQL言語リファレンス』 

その他のリモート・オブジェクト間の依存性

Oracle Databaseでは、ローカル・プロシージャとリモート・プロシージャの間の依存性を除いては、リモート・スキーマ・オブジェクト間の依存性は管理されません。

たとえば、リモート表を参照する問合せによって、ローカル・ビューを作成して定義するとします。また、ローカル・プロシージャに、同じリモート表を参照するSQL文が含まれているとします。その後、表の定義が変更されたとします。

表の変更後にビューとプロシージャが使用され、そのビューとプロシージャがエラーとなった場合でも、ローカル・ビューとプロシージャは無効になりません。この場合、ビューとプロシージャを、エラーが戻されないように手動で変更する必要があります。このような場合は、依存オブジェクトを不必要に再コンパイルするより、依存性を管理しないことをお薦めします。

アプリケーションの依存性

データベース・アプリケーションのコードでは、接続されているデータベース内のオブジェクトを参照できます。たとえば、OCIおよびプリコンパイラ・アプリケーションは、無名PL/SQLブロックを発行できます。Oracle Formsアプリケーション内のトリガーは、スキーマ・オブジェクトを参照できます。

このようなアプリケーションは、参照するスキーマ・オブジェクトに依存しています。依存性管理の方法は、開発環境によって異なります。Oracle Databaseでは、アプリケーション間の依存性の追跡は、自動的には行われません。

関連項目

データベース・アプリケーション内でリモート依存性を管理する方法の詳細は、アプリケーション開発ツール固有およびオペレーティング・システム固有のマニュアルを参照してください。 

リモート・プロシージャ・コール(RPC)の依存性管理

リモート・プロシージャ・コール(RPC)の依存性管理が行われるのは、分散データベース・システムでローカル・ストアド・プロシージャによりリモート・プロシージャがコールされる場合です。

この項の内容は、次のとおりです。

タイムスタンプのチェック

タイムスタンプのチェックの依存性モデルでは、プロシージャがコンパイルまたは再コンパイルされるたびに、そのタイムスタンプ(作成、変更または置換された時刻)がデータ・ディクショナリに記録されます。タイムスタンプは、プロシージャが作成、変更または置換された時刻の記録です。さらに、コンパイル済プロシージャには、それが参照するリモート・プロシージャごとに、スキーマ、パッケージ名、プロシージャ名、タイムスタンプなどの情報も含まれています。

依存プロシージャが使用されると、Oracle Databaseは、コンパイル時に記録されたリモート・タイムスタンプと、リモートで参照されたプロシージャのカレント・タイムスタンプを比較します。比較結果に応じて、次の2つの処理が発生します。

ローカル・プロシージャ本体の文によりリモート・プロシージャが実行されると、実際のタイムスタンプが比較されます。分散データベースの通信リンクを使用してタイムスタンプが比較されるのは、このときのみです。したがって、ローカル・プロシージャの文のうち無効なプロシージャ・コールより前にあるすべての文は、正常に実行される可能性があります。無効なプロシージャ・コールより後の文はまったく実行されません。コンパイルが必要です。

無効なプロシージャ・コールの実行方法によっては、その前に実行されたDML文がロールバックされます。たとえば、次の例では、PL/SQLブロックの変更全体がロールバックされるため、UPDATEの結果はロールバックされます。

BEGIN
UPDATE table set ...
invalid_proc;
COMMIT;
END;

ただし、次の例では、UPDATEの結果は確定されます。この場合、ロールバックされるのはPROCコールのみです。

UPDATE table set ...
EXECUTE invalid_proc;
COMMIT;

タイムスタンプを使用してPL/SQLプログラム・ユニット間の依存性を処理する場合は、プログラム・ユニットまたは関連するスキーマ・オブジェクトを変更するたびに、そのすべての依存ユニットに無効のマークが付けられるため、実行するためには再コンパイルする必要があります。

各プログラム・ユニットでは、作成時または再コンパイル時にサーバーで設定されたタイムスタンプが保持されます。図6-1は、それを図示したものです。まず、プロシージャP1およびP2は、ストアド・プロシージャP3をコールします。ストアド・プロシージャP3は表T1を参照します。この例では、各プロシージャはいずれも表T1に依存しています。P3T1に直接依存しますが、P1およびP2T1に間接的に依存します。

図6-1    依存関係


画像の説明

P1およびP2P3と同じサーバー上にある場合にP3が変更されると、すぐに無効のマークが付けられます。P1およびP2がコンパイルされた状態では、P3のタイムスタンプのレコードが含まれています。そのため、プロシージャP3が変更され再コンパイルされた場合、P3上のタイムスタンプは、P1およびP2のコンパイル中にP3に対して記録された値とは一致しなくなります。

P1およびP2は、クライアント・システム上または分散環境内の別のOracle Databaseインスタンス上にある場合、実行時にタイムスタンプ情報を使用してこの2つのプロシージャに無効のマークが付けられます。

この依存性モデルのデメリットは、必要以上に制限が多いということです。ネットワークを介した依存オブジェクトは、必ずしも必要でないときにも再コンパイルされることが多いため、パフォーマンスが低下します。

さらに、クライアント側アプリケーションがPL/SQLバージョン2を使用して作成されている場合、クライアント側では、タイムスタンプ・モデルによりアプケーションの実行が完全にブロックされる状況が生じることがあります。PL/SQLバージョン1が、ストアド・プロシージャをサポートしていなかったため、クライアント側でPL/SQLバージョン1を使用していたOracle Formsなどの初期のリリースのツールでは、この依存性モデルは使用されていませんでした。

クライアント側のPL/SQLバージョン2と統合されたOracle Formsのリリースの場合、タイムスタンプ・モデルで問題が発生する場合があります。たとえば、そのアプリケーションが使用するクライアント側PL/SQLプロシージャがクライアント・サイトで再コンパイルされないかぎり、アプリケーションはインストール中に無効になります。また、クライアント側のプロシージャがサーバー側のプロシージャに依存しており、そのサーバー側のプロシージャが変更または自動的に再コンパイルされた場合は、クライアント側のPL/SQLプロシージャを再コンパイルする必要があります。ただし、多くのアプリケーション環境(Formsランタイム・アプリケーションなど)では、クライアントで使用できるPL/SQLコンパイラはありません。このため、アプリケーションはまったく実行できません。このような場合、クライアント・アプリケーションの開発者は、すべての顧客に対してそのアプリケーションの新しいバージョンを再配布する必要があります。

シグネチャのチェック

Oracle Databaseには、RPCシグネチャを使用するリモート依存性の機能もあります。RPCシグネチャ機能の影響を受けるのは、リモート依存性のみです。ローカル依存性は、その環境でいつでも再コンパイルできるため影響を受けません。

プロシージャのRPCシグネチャには、次の項目に関する情報が含まれます。

RPCシグネチャ依存性モデルが有効である場合に、依存単位に親単位のプロシージャへのコールが含まれており、かつ、そのプロシージャのRPCシグネチャが互換性のない方法で変更されていると、リモート・プログラム・ユニットへの依存性により、その依存単位が無効になります。プログラム・ユニットは、パッケージ、ストアド・プロシージャ、ストアド・ファンクションまたはトリガーのいずれかです。

タイムスタンプのみの依存性モデルに伴う問題をできるかぎり解消するため、Oracle Databaseには、RPCシグネチャを使用するリモート依存性の機能が追加されています。RPCシグネチャ機能の影響を受けるのは、リモート依存性のみです。ローカル(同一サーバー内での)依存性は、その環境でいつでも再コンパイルできるため影響を受けません。

コンパイル済のストアド・プログラム・ユニットには、それぞれにRPCシグネチャが関連付けられています。RPCシグネチャは、次の基準に従って各ユニットを識別しています。

ユーザーは、リモート依存性の管理にRPCシグネチャとタイムスタンプのどちらを使用するかを制御できます。

関連項目

「リモート依存性の制御」 

RPCシグネチャ依存性モデルが使用されている場合に、依存単位に親単位のサブプログラムへのコールが含まれており、かつ、そのサブプログラムのRPCシグネチャが互換性のない方法で変更されていると、リモート・プログラム・ユニットへの依存性により、その依存単位が無効になります。

たとえば、ボストンのサーバー(BOSTON_SERVER)に格納されているプロシージャget_emp_nameを考えます。このプロシージャは、次のように定義されています。

CREATE OR REPLACE PROCEDURE get_emp_name (
   emp_number   IN  NUMBER,
   hire_date    OUT VARCHAR2,
   emp_name     OUT VARCHAR2) AS
BEGIN
   SELECT ename, to_char(hiredate, 'DD-MON-YY')
      INTO emp_name, hire_date
      FROM emp
      WHERE empno = emp_number;
END;

get_emp_nameBOSTON_SERVERでコンパイルされると、RPCシグネチャはタイムスタンプとともに記録されます。

次のように、カリフォルニアにある別のサーバーで、PL/SQLコードにより、BOSTON_SERVERというDBリンクで識別されるget_emp_nameがコールされるとします。

CREATE OR REPLACE PROCEDURE print_ename (emp_number IN NUMBER) AS
   hire_date    VARCHAR2(12);
   ename        VARCHAR2(10);
BEGIN
   get_emp_name@BOSTON_SERVER(emp_number, hire_date, ename);
   dbms_output.put_line(ename);
   dbms_output.put_line(hire_date);
END;

このカリフォルニアのサーバー・コードがコンパイルされるときに、次の処理が実行されます。

実行時には変更の有無にかかわらず、カリフォルニアのサーバーからボストンのサーバーへのリモート・プロシージャのコール中に、print_enameのコンパイルされた状態で保存されているget_emp_nameの記録済RPCシグネチャが、ボストンのサーバーまで送信されます。

タイムスタンプ依存性モードが有効な場合、タイムスタンプに不一致があると、コール側プロシージャにエラー・ステータスが戻されます。

ただし、RPCシグネチャ・モードが有効な場合は、タイムスタンプの不一致は無視され、カリフォルニアのサーバーのprint_enameのコンパイル済状態にあるget_emp_nameの記録済RPCシグネチャが、ボストンのサーバーにあるget_emp_nameの現在のRPCシグネチャと比較されます。この2つのシグネチャが一致した場合、コールは正常に完了します。一致しない場合は、エラー・ステータスがprint_nameプロシージャに戻されます。

ボストンのサーバー上にあるget_emp_nameプロシージャが変更されているか、または新しいリリースのサーバーがインストールされたなどの理由で、そのタイムスタンプがカリフォルニアのサーバー上にあるprint_nameプロシージャに記録されているタイムスタンプと異なる可能性があります。カリフォルニアのサーバーでRPCシグネチャ・リモート依存性モードが有効になっているかぎり、タイムスタンプに不一致があっても、get_emp_nameのコール時にエラーが発生することはありません。


注意

DETERMINISTICPARALLEL_ENABLEおよび純粋度情報は、RPCシグネチャ・モードでは表示されません。リモート・システム上のファンクションが別の設定で再定義された場合、これらの設定に基づく最適化は自動的には再考慮されません。そのため、SQL文でリモート・ファンクションへのコールが(間接的にでも)発生した場合、またはファンクション索引でリモート・ファンクションが(間接的にでも)使用された場合、問合せ結果は正しくないことがあります。 


この項の内容は、次のとおりです。

データ型クラスの切替え

RPCシグネチャは、あるクラスのデータ型を別のクラスに切り替えた場合に変更されます。1つのデータ型クラスには、複数のデータ型が含まれる可能性があります。同じクラスの中でパラメータのデータ型を別のデータ型に変更した場合は、RPCシグネチャは変更されません。

表6-3は、データ型クラスとそこに含まれるデータ型をリストにまとめたものです。NCHARTIMESTAMPなど、表6-3にリストされていないデータ型は、いずれのクラスの一部でもありません。したがって、それらのデータ型を変更した場合は必ず、RPCシグネチャに不一致が発生します。

表6-3    データ型クラス 
データ型クラス  クラス内のデータ型 

Character 

CHAR
CHARACTER
 

VARCHAR 

VARCHAR
VARCHAR2
STRING
LONG
ROWID
 

RAW 

RAW
LONG RAW
 

Integer 

BINARY_INTEGER
PLS_INTEGER
SIMPLE_INTEGER
BOOLEAN
NATURAL
NATURALN
POSITIVE
POSITIVEN
 

Number 

NUMBER
INT
INTEGER
SMALLINT
DEC
DECIMAL
REAL
FLOAT
NUMERIC
DOUBLE PRECISION
 

Date 

DATE
TIMESTAMP
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH LOCAL TIME ZONE
INTERVAL YEAR TO MONTH
INTERVAL DAY TO SECOND
 
モード

デフォルトのパラメータ・モードINの明示的指定に変更があっても、サブプログラムのRPCシグネチャは変更されません。たとえば、次の2つを入れ換えます。

PROCEDURE P1 (Param1 NUMBER);
PROCEDURE P1 (Param1 IN NUMBER);

入れ換えても、RPCシグネチャは変更されません。これ以外のパラメータ・モードの変更が行われた場合、RPCシグネチャは変更されます。

デフォルトのパラメータ値

デフォルトのパラメータ値の指定を変更しても、RPCシグネチャは変更されません。たとえば、P1は、次の2つの例では同じRPCシグネチャを持っています。

PROCEDURE P1 (Param1 IN NUMBER := 100);
PROCEDURE P1 (Param1 IN NUMBER := 200);

コール側で新しいデフォルト値を取得できるようにする必要がある場合、アプリケーション開発者はコールされたプロシージャを再コンパイルする必要があります。ただし、デフォルトのパラメータ値の割当てが変更されても、RPCシグネチャに基づいて無効化されることはありません。

プロシージャ・シグネチャの変更例

この章ですでに説明したGet_emp_namesプロシージャの本体を、次のように変更するとします。

DECLARE
   Emp_number  NUMBER;
   Hire_date   DATE;
BEGIN
-- date format model changes
  
   SELECT Ename, To_char(Hiredate, 'DD/MON/YYYY')
      INTO Emp_name, Hire_date
      FROM Emp_tab
      WHERE Empno = Emp_number;
END;

プロシージャ仕様部は変更されていないため、そのRPCシグネチャも変更されていません。

ただし、プロシージャ仕様部が次のように変更されたとします。

CREATE OR REPLACE PROCEDURE Get_emp_name (
   Emp_number  IN  NUMBER,
   Hire_date   OUT DATE,
   Emp_name    OUT VARCHAR2) AS

この場合、パラメータHire_dateが別のデータ型になっているため、それに応じて本体が変更された場合、RPCシグネチャは変更されます。

ただし、そのパラメータの名前がWhen_hiredに変更されても、データ型はVARCHAR2、モードはOUTのままの場合、RPCシグネチャは変更されません。仮パラメータの名前が変更されても、そのユニットのRPCシグネチャは変更されません。

次の例を考えてみます。

CREATE OR REPLACE PACKAGE Emp_package AS
    TYPE Emp_data_type IS RECORD (
        Emp_number NUMBER,
        Hire_date  VARCHAR2(12),
        Emp_name   VARCHAR2(10));
    PROCEDURE Get_emp_data
        (Emp_data IN OUT Emp_data_type);
END;

CREATE OR REPLACE PACKAGE BODY Emp_package AS
    PROCEDURE Get_emp_data
        (Emp_data IN OUT Emp_data_type) IS
   BEGIN
       SELECT Empno, Ename, TO_CHAR(Hiredate, 'DD/MON/YY')
           INTO Emp_data
           FROM Emp_tab
           WHERE Empno = Emp_data.Emp_number;
   END;
END;

レコードのフィールド名が変更されるようにパッケージ仕様部が変更された場合、型がそのままである場合は、RPCシグネチャには影響しません。たとえば、次のパッケージ仕様部は、前述したパッケージ仕様部の例と同じRPCシグネチャを持っています。

CREATE OR REPLACE PACKAGE Emp_package AS
    TYPE Emp_data_type IS RECORD (
        Emp_num    NUMBER,         -- was Emp_number
        Hire_dat   VARCHAR2(12),   -- was Hire_date
        Empname    VARCHAR2(10));  -- was Emp_name
    PROCEDURE Get_emp_data
        (Emp_data IN OUT Emp_data_type);
END;

型が以前のままである場合は、パラメータ型の名前を変更してもRPCシグネチャは変更されません。たとえば、次のようなEmp_packageのパッケージ仕様部は、最初のものと同じです。

CREATE OR REPLACE PACKAGE Emp_package AS
    TYPE Emp_data_record_type IS RECORD (
        Emp_number NUMBER,
        Hire_date  VARCHAR2(12),
        Emp_name   VARCHAR2(10));
    PROCEDURE Get_emp_data
        (Emp_data IN OUT Emp_data_record_type);
END;

リモート依存性の制御

動的初期化パラメータREMOTE_DEPENDENCIES_MODEは、タイムスタンプとRPCシグネチャのどちらで依存性モデルを有効にするかを制御します。

この場合は、タイムスタンプのみを使用して依存性が解決されます(明示的な上書きが動的に行われない場合)。

この場合は、RPCシグネチャを使用して依存性が解決されます(明示的な上書きが動的に行われない場合)。

REMOTE_DEPENDENCIES_MODEパラメータがinit.oraパラメータ・ファイル内で指定されていないか、DDL文ALTER SESSIONまたはALTER SYSTEMを使用してパラメータが指定されていない場合は、TIMESTAMPがデフォルト値となります。そのため、明示的にREMOTE_DEPENDENCIES_MODEパラメータまたは適切なDDL文を使用しないかぎり、サーバーはタイムスタンプ依存性モデルを使用して動作します。

REMOTE_DEPENDENCIES_MODE=SIGNATUREを使用する場合:

この項の内容は、次のとおりです。

依存性の解決

REMOTE_DEPENDENCIES_MODE = TIMESTAMP(デフォルト値)の場合、プログラム・ユニット間の依存性は、実行時にタイムスタンプを比較して処理されます。コールされたリモート・プロシージャのタイムスタンプが、コールされたプロシージャのタイムスタンプが一致しない場合、コール側の(依存)ユニットは無効になり、再コンパイルする必要があります。この場合、ローカルPL/SQLコンパイラがない場合は、コール側のアプリケーションを処理できません。

タイムスタンプ依存性モードでは、RPCシグネチャは比較されません。ローカルPL/SQLコンパイラがある場合は、コール側プロシージャが実行されると自動的に再コンパイルされます。

REMOTE_DEPENDENCIES_MODE = SIGNATUREの場合、コール側のユニットの記録済タイムスタンプは、まず最初にコールされたリモート・ユニット内の現在のタイムスタンプと比較されます。2つのタイムスタンプが一致した場合、コールが進行します。タイムスタンプが一致しない場合は、コールされたリモート・サブプログラムのRPCシグネチャは、コール側サブプログラムに記録されたままの状態で、コールされたサブプログラムの現在のRPCシグネチャと比較されます。この2つのシグネチャが一致しない場合は、「データ型クラスの切替え」に記載されている基準を使用した結果、コール側セッションにエラーが戻されます。

依存性を管理するための提案

次のガイドラインに従って、REMOTE_DEPENDENCIES_MODEパラメータを設定してください。

共有SQLの依存性管理

スキーマ・オブジェクト相互間の依存性管理に加えて、Oracle Databaseは共有プール内の各共有SQL領域の依存性も管理します。表またはビュー、シノニム、順序を生成、変更または削除したり、プロシージャまたはパッケージ仕様部を再コンパイルすると、それらに依存する共有SQL領域もすべて無効になります。共有SQL領域が無効になった後で、その領域に対応するカーソルを実行すると、Oracle DatabaseによってSQL文が再解析され、共有SQL領域が再生成されます。


戻る 次へ
Oracle
Copyright © 1993, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引