Oracle Database 概要 11gリリース1(11.1) E05765-03 |
|
オブジェクト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つの問合せによる出力を示しています。
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
に依存しています。
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;
静的データ・ディクショナリ・ビューUSER_DEPENDENCIES
、ALL_DEPENDENCIES
およびDBA_DEPENDENCIES
には、データベース・オブジェクト間の依存性が表示されます。
utldtree.sql
SQLスクリプトを実行すると、オブジェクト依存性ツリーに関する情報が表示されるビューDEPTREE
、ビューIDEPTREE
およびあらかじめソートされ整形表示されるDEPTREE
が作成されます。
各データベース・オブジェクトには、表6-1に示されているいずれかのステータス値が割り当てられています。
ステータス | 意味 |
---|---|
有効 |
データ・ディクショナリ内の現在の定義を使用して正常にコンパイルされた。 |
コンパイル・エラー |
直前のコンパイル実行中にエラーが発生した。 |
無効 |
参照先のオブジェクトが変更されたために無効のマークが付けられている。(無効になるのは依存オブジェクトのみ。) |
権限取消し |
参照オブジェクトに対するアクセス権限が取り消された。(権限取消しの対象となるのは依存オブジェクトのみ。) |
オブジェクトAがオブジェクトBに、オブジェクトBがオブジェクトCにそれぞれ依存している場合、A、Bはそれぞれ、B、Cへの直接依存性を持ち、AはCへの間接依存性を持ちます。
直接依存性は、それ自体に影響を与える変更(参照オブジェクトのシグネチャに対する変更)を参照オブジェクトに対して加えた場合にのみ無効になります。
間接依存性は、それ自体に影響を与えない変更を参照オブジェクトに対して加えることにより無効にできます。たとえば、Cを変更したことによりBが無効になると、A(およびBへの直接依存性と間接依存性のすべて)も無効になります。これを連鎖的な無効化と呼びます。
表6-2は、各オブジェクトに対して、それが依存する他のオブジェクトに変更があった場合どのような影響があるかを示したものです。
操作 | 影響のあった依存オブジェクトのステータス |
---|---|
|
次の場合は
これ以外の場合は変更なし。 |
|
次の場合は
これ以外の場合は変更なし。 |
オンライン表再定義( |
新しい定義の列リストと以前の定義の列リストが異なり、少なくとも次の1つに該当する場合は
これ以外の場合は変更なし。 |
|
次の場合は
これ以外の場合は変更なし。 |
|
|
|
次の場合、索引が構築されている表の依存性は |
|
|
|
コール・シグネチャが変更された場合は プロシージャ本体やファンクション本体への変更など、これ以外の変更に対しては有効。 |
|
次の場合は
これ以外の場合は変更なし。 |
|
変更なし。 |
|
|
|
|
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コンパイラでは、無効なオブジェクトの再コンパイルが行われます。オブジェクトは、再コンパイル中にエラーが発生しなければ再有効化されます。エラーが発生した場合は無効のままです。
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;
次の文を実行すると、pkg1
(tab1
に依存)が無効になります。これにより、proc1
(pkg1
に依存)も連鎖的に無効となります。
ALTER TABLE tab1 ADD(v VARCHAR2(20));
ただし、pkg1.p
のシグネチャは変更されていないため、PL/SQLコンパイラでは、proc1
を再コンパイルすることなく再度有効にすることができます。
SQL文で参照されているオブジェクトの名前は、1つ以上の要素で構成されています。各構成要素は、ピリオドで区切られます(例: hr.employees.department_id
)。
Oracle Databaseでは、次の手順に従ってオブジェクト名の解決が実行されます。
オブジェクト名に要素が1つしかない場合は、その要素が最初の要素となります。要素が2つ以上ある場合は、最も左にあるピリオドの左側の要素が先頭の要素です。たとえば、hr.employees.department_id
では、hr
が先頭の要素です。
先頭の要素を修飾する手順は次のとおりです。
SELECT
文のFROM
句に含まれる表名であり、かつ2つ以上の構成要素を持つ場合は、手順dに進みます。それ以外の場合は、手順bに進みます。
該当するスキーマが見つかった場合、オブジェクト名に後続の要素があれば、手順eに進みます。それ以外の場合は、エラーが戻され、オブジェクト名を修飾できません。
該当する組込みファンクションが見つかった場合は、スキーマによりその組込みファンクションが再定義されています。オフジェクト名は、スキーマによって定義された同名のファンクションではなく、元の組込みファンクションに解決されます。手順2に進みます。
該当する組込みファンクションが見つからなかった場合は、エラーが戻され、オブジェクト名を修飾できません。
たとえば、オブジェクト名がhr.employees.department_id
である場合、hr
がスキーマとして修飾されます。employees
が表として修飾されている場合、department_id
はその表の列に対応する必要があります。また、employees
がパッケージとして修飾されている場合、department_id
はそのパッケージのパブリック定数、変数、プロシージャまたはファンクションに対応する必要があります。
Oracle Databaseによる参照の解決では、オブジェクトは、他のオブジェクトが存在しないという事実に依存する場合があります。このような状況が発生するのは、依存オブジェクトで使用されている参照の解釈が、別のオブジェクトの存在により多義的になる場合です。
ローカル依存性の管理が行われるのは、Oracle Databaseにおいて、単一データベース内のオブジェクト間で依存性が管理される場合です。たとえば、プロシージャ内の文が、同じデータベース内の表を参照する場合があります。
リモート依存性の管理が行われるのは、Oracle Databaseにおいて、ネットワークを介した分散環境で依存性が管理される場合です。たとえば、Oracle Formsトリガーは、データベース内のスキーマ・オブジェクトに依存する場合があります。また、分散データベースにおいて、ローカル・ビューの定義問合せがリモート表を参照する場合があります。
Oracle Databaseでは、分散データベースの依存性の管理も行われます。たとえば、Oracle Formsアプリケーション内のトリガーが表を参照する場合があります。データベース・システムでは、このようなオブジェクト間の依存性を管理する必要があります。Oracle Databaseでは、関係するオブジェクトの種類によっては、リモート依存性を管理するために別のメカニズムが使用されます。
この項の内容は、次のとおりです。
ファンクション、パッケージ、トリガーなど、ストアド・プロシージャの相互間の依存性は、分散データベース・システムにおいてはタイムスタンプのチェックまたはシグネチャのチェックを使用して管理されます(「タイムスタンプのチェック」および「シグネチャのチェック」を参照してください)。
タイムスタンプとシグネチャのどちらでリモート依存性を管理するかについては、動的初期化パラメータREMOTE_DEPENDENCIES_MODE
で指定します。
Oracle Databaseでは、ローカル・プロシージャとリモート・プロシージャの間の依存性を除いては、リモート・スキーマ・オブジェクト間の依存性は管理されません。
たとえば、リモート表を参照する問合せによって、ローカル・ビューを作成して定義するとします。また、ローカル・プロシージャに、同じリモート表を参照するSQL文が含まれているとします。その後、表の定義が変更されたとします。
表の変更後にビューとプロシージャが使用され、そのビューとプロシージャがエラーとなった場合でも、ローカル・ビューとプロシージャは無効になりません。この場合、ビューとプロシージャを、エラーが戻されないように手動で変更する必要があります。このような場合は、依存オブジェクトを不必要に再コンパイルするより、依存性を管理しないことをお薦めします。
データベース・アプリケーションのコードでは、接続されているデータベース内のオブジェクトを参照できます。たとえば、OCIおよびプリコンパイラ・アプリケーションは、無名PL/SQLブロックを発行できます。Oracle Formsアプリケーション内のトリガーは、スキーマ・オブジェクトを参照できます。
このようなアプリケーションは、参照するスキーマ・オブジェクトに依存しています。依存性管理の方法は、開発環境によって異なります。Oracle Databaseでは、アプリケーション間の依存性の追跡は、自動的には行われません。
リモート・プロシージャ・コール(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
に依存しています。P3
はT1
に直接依存しますが、P1
およびP2
はT1
に間接的に依存します。
P1
およびP2
がP3
と同じサーバー上にある場合に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シグネチャは、次の基準に従って各ユニットを識別しています。
IN
、OUT
およびIN
OUT
)
ユーザーは、リモート依存性の管理に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_name
がBOSTON_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;
このカリフォルニアのサーバー・コードがコンパイルされるときに、次の処理が実行されます。
get_emp_name
のRPCシグネチャが、カリフォルニアのサーバーに転送されます。
print_ename
のコンパイルされた状態で記録されます。
実行時には変更の有無にかかわらず、カリフォルニアのサーバーからボストンのサーバーへのリモート・プロシージャのコール中に、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
のコール時にエラーが発生することはありません。
この項の内容は、次のとおりです。
RPCシグネチャは、あるクラスのデータ型を別のクラスに切り替えた場合に変更されます。1つのデータ型クラスには、複数のデータ型が含まれる可能性があります。同じクラスの中でパラメータのデータ型を別のデータ型に変更した場合は、RPCシグネチャは変更されません。
表6-3は、データ型クラスとそこに含まれるデータ型をリストにまとめたものです。NCHAR
やTIMESTAMP
など、表6-3にリストされていないデータ型は、いずれのクラスの一部でもありません。したがって、それらのデータ型を変更した場合は必ず、RPCシグネチャに不一致が発生します。
デフォルトのパラメータ・モード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シグネチャを使用して依存性が解決されます(明示的な上書きが動的に行われない場合)。
ALTER SESSION SET REMOTE_DEPENDENCIES_MODE = {SIGNATURE | TIMESTAMP} Thise example alters the dependency model systemwide after startup: ALTER SYSTEM SET REMOTE_DEPENDENCIES_MODE = {SIGNATURE | TIMESTAMP}
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
パラメータを設定してください。
TIMESTAMP
に設定して(またはこれをデフォルト値にして)、タイムスタンプ依存性モードにできます。
SIGNATURE
に設定する必要があります。この設定をすると、次のことができます。
スキーマ・オブジェクト相互間の依存性管理に加えて、Oracle Databaseは共有プール内の各共有SQL領域の依存性も管理します。表またはビュー、シノニム、順序を生成、変更または削除したり、プロシージャまたはパッケージ仕様部を再コンパイルすると、それらに依存する共有SQL領域もすべて無効になります。共有SQL領域が無効になった後で、その領域に対応するカーソルを実行すると、Oracle DatabaseによってSQL文が再解析され、共有SQL領域が再生成されます。
|
Copyright © 1993, 2008 Oracle Corporation. All Rights Reserved. |
|