18 スキーマ・オブジェクトの管理

Oracle Databaseで複数のタイプのスキーマ・オブジェクトを作成および管理できます。

18.1 一度の操作で複数の表やビューを作成する方法

CREATE SCHEMA文を使用すると、一度の操作で複数の表やビューを作成し、権限を付与できます。個々の表やビューの作成が失敗したり、権限の付与が失敗したりすると、文全体がロールバックされます。オブジェクトは作成されず、権限も付与されません。

具体的には、CREATE SCHEMA文には、CREATE TABLECREATE VIEWおよびGRANTのみを含めることができます。指定した文を発行するための権限を持っている必要があります。実際にスキーマが作成されるのではなく、スキーマはCREATE USER文を使用してユーザーを作成したときに作成されます。そのかわりに、この文はスキーマを移入します。

次の文は、2つの表とそれらのデータを結合するビューを作成します。

CREATE SCHEMA AUTHORIZATION scott
    CREATE TABLE dept (
        deptno NUMBER(3,0) PRIMARY KEY,
        dname VARCHAR2(15),
        loc VARCHAR2(25))
    CREATE TABLE emp (
        empno NUMBER(5,0) PRIMARY KEY,
        ename VARCHAR2(15) NOT NULL,
        job VARCHAR2(10),
        mgr NUMBER(5,0),
        hiredate DATE DEFAULT (sysdate),
        sal NUMBER(7,2),
        comm NUMBER(7,2),
        deptno NUMBER(3,0) NOT NULL
        CONSTRAINT dept_fkey REFERENCES dept)
   CREATE VIEW sales_staff AS
        SELECT empno, ename, sal, comm
        FROM emp
        WHERE deptno = 30
        WITH CHECK OPTION CONSTRAINT sales_staff_cnst
        GRANT SELECT ON sales_staff TO human_resources;

CREATE SCHEMA文は、STORAGE句など、ANSIのCREATE TABLE文とCREATE VIEW文を拡張したOracle Database独自の機能をサポートしていません。

関連項目:

CREATE SCHEMA文の構文と詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.2 表、索引およびクラスタの分析

スキーマ・オブジェクトに関する統計を収集し、統計を分析し、スキーマ・オブジェクトを検証できます。

18.2.1 表、索引およびクラスタの分析について

スキーマ・オブジェクトに関する情報を収集して、その情報を分析できます。

次の目的でスキーマ・オブジェクト(表、索引またはクラスタ)を分析します。

  • 統計の収集と管理

  • 記憶形式の妥当性の検証

  • 表またはクラスタの移行行と連鎖行の識別

ノート:

オプティマイザ統計の収集に、ANALYZECOMPUTE句およびESTIMATE句を使用しないでください。これらの句は非推奨になりました。かわりに、DBMS_STATSパッケージを使用します。このパッケージでは、パラレルでの統計の収集、パーティション化されたオブジェクトのグローバル統計の収集、その他の方法での統計収集の微調整を行うことができます。統計に依存するコストベース・オプティマイザでは、最終的にはDBMS_STATSを使用して収集された統計のみが使用されます。DBMS_STATSパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

コストベース・オプティマイザに関連しない統計収集には、ANALYZE文(DBMS_STATSではなく)を使用する必要があります。たとえば、次のような場合です。

  • VALIDATE句、LIST CHAINED ROWS句の使用

  • 空きリスト・ブロックの情報を収集する場合

18.2.2 DBMS_STATSを使用した表および索引統計の収集

DBMS_STATSパッケージまたはANALYZE文を使用して、表、索引またはクラスタの物理記憶特性の統計を収集できます。これらの統計はデータ・ディクショナリに格納され、オプティマイザで使用して、分析対象オブジェクトにアクセスするSQL文に最も効率的な実行計画を選択できます。

オプティマイザ統計の収集には、より多様性のあるDBMS_STATSパッケージを使用することをお薦めしますが、空きブロックや平均容量など、オプティマイザに関連付けられていない統計の収集にはANALYZE文を使用する必要があります。

DBMS_STATSパッケージを使用すると、パラレル実行を利用した統計収集と統計の外部操作ができます。統計をデータ・ディクショナリ以外の表に格納し、オプティマイザに影響を与えずにその統計を操作できます。統計をデータベース間でコピーしたり、バックアップ・コピーを作成できます。

次のDBMS_STATSプロシージャにより、オプティマイザ統計を収集できます。

18.2.3 表、索引、クラスタおよびマテリアライズド・ビューの妥当性チェック

表、索引、クラスタまたはマテリアライズド・ビューの構造の整合性を検証するには、VALIDATE STRUCTUREオプションを指定したANALYZE文を使用します。

構造が有効な場合、エラーは返されません。しかし、構造が破損していると、エラー・メッセージが出力されます。

たとえば、ハードウェアやその他のシステムに障害が発生した場合、索引が破損し、正しく機能しなくなる可能性があります。索引の妥当性をチェックすると、索引内のすべてのエントリが、対応付けられた表の正しい行を示しているかを確認できます。索引が破損した場合は、その索引を削除して再作成できます。

表、索引またはクラスタが破損している場合は、削除して再作成します。マテリアライズド・ビューが破損している場合は、完全リフレッシュを実行し、問題が修正されたことを確認します。問題が修正されない場合は、マテリアライズド・ビューを削除して再作成します。

次の文は、emp表を分析します。

ANALYZE TABLE emp VALIDATE STRUCTURE;

CASCADEオプションを含めると、オブジェクトとすべての依存オブジェクト(索引など)の妥当性をチェックできます。次の文は、emp表と、それに対応付けられているすべての索引の妥当性をチェックします。

ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE;

デフォルトでは、CASCADEオプションによって、完全な妥当性チェックが実行されます。この操作はリソースを消費する可能性があるため、FAST句を使用してより高速なバージョンの妥当性チェックを実行できます。このバージョンでは、最適化されたチェック・アルゴリズムを使用して破損の有無をチェックしますが、破損の詳細はレポートしません。FASTチェックで破損が検出された場合は、FAST句を指定せずにCASCADEオプションを使用すると、破損箇所を特定できます。次の文では、emp表と、それに対応付けられているすべての索引の妥当性チェックを高速に実行します。

ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE FAST;

高速な検証を実行しても非常に長い時間がかかる場合は、SQL問合せを使用して索引を個別に検証できます。「問合せによる表および索引の相互検証」を参照してください。

妥当性をチェックするオブジェクトに対してDMLを実行している間でも、オンラインで構造の妥当性をチェックするように指定できます。オブジェクトに影響を及ぼす実行中のDMLによって妥当性が包括的でなくなりますが、これはオンラインでANALYZEを実行できる柔軟性によって相殺されます。次の文は、emp表と、それに対応付けられているすべての索引の妥当性をオンラインでチェックします。

ANALYZE TABLE emp VALIDATE STRUCTURE CASCADE ONLINE;

関連項目:

ANALYZE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.2.4 問合せによる表および索引の相互検証

ANALYZE文の完了には、非常に長い時間がかかる場合があります。そのような場合は、SQL問合せを使用して索引を検証できます。

問合せによって、表と索引との間に矛盾があることが確認された場合は、ANALYZE文を使用して、索引を詳細に分析できます。通常、データベース内のほとんどのオブジェクトは破損していないため、この簡単な問合せを使用して、多数の表を破損の候補として削除し、破損している可能性のある表のみでANALYZE文を使用できます。

索引を検証するには、次の問合せを実行します。

SELECT /*+ FULL(ALIAS) PARALLEL(ALIAS, DOP) */ SUM(ORA_HASH(ROWID))
   FROM table_name ALIAS 
   WHERE ALIAS.index_column IS NOT NULL 
      MINUS SELECT /*+ INDEX_FFS(ALIAS index_name) 
      PARALLEL_INDEX(ALIAS, index_name, DOP) */ SUM(ORA_HASH(ROWID)) 
   FROM table_name ALIAS WHERE ALIAS.index_column IS NOT NULL;

問合せを実行するときに、次の内容を置換します。

  • table_nameプレースホルダに表の名前を入力します。

  • index_columnプレースホルダに索引列を入力します。

  • index_nameプレースホルダに索引名を入力します。

問合せによって行が返される場合、矛盾が発生している可能性があるため、ANALYZE文を使用して診断できます。

関連項目:

ANALYZE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.2.5 表とクラスタの連鎖行のリスト

表またはクラスタの連鎖行と移行行は、LIST CHAINED ROWS句を指定したANALYZE文を使用して検出できます。この文の結果は、LIST CHAINED ROWS句によって返される情報を受け入れるために明示的に作成した指定の表に格納されます。この結果は、行を更新するための領域が十分であるかどうかを判断するうえで役立ちます。

18.2.5.1 CHAINED_ROWS表の作成

ANALYZE...LIST CHAINED ROWS文によって返されるデータを格納する表を作成するには、UTLCHAIN.SQLまたはUTLCHN1.SQLスクリプトを実行します。

これらのスクリプトは、データベースに付属しています。これらのスクリプトは、スクリプトを実行するユーザーのスキーマ内にCHAINED_ROWSという名前の表を作成します。

ノート:

CHAINED_ROWS表を作成するためにどちらのスクリプトを実行するかは、データベースの互換性レベルと分析する表のタイプによって決まります。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

CHAINED_ROWS表を作成した後、ANALYZE文のINTO句にその表を指定します。たとえば、次の文は、CHAINED_ROWS表に、emp_deptクラスタ内の連鎖行に関する情報を含む行を挿入します。

ANALYZE CLUSTER emp_dept LIST CHAINED ROWS INTO CHAINED_ROWS;

関連項目:

18.2.5.2 表内の移行行または連鎖行の解消

CHAINED_ROWS表の情報を使用すると、既存表内にある移行行と連鎖行を低減または解消できます。

次の手順を実行します。

  1. ANALYZE文を使用して、移行行と連鎖行に関する情報を収集します。
    ANALYZE TABLE order_hist LIST CHAINED ROWS;
    
  2. 出力表を問い合せます。
    SELECT *
    FROM CHAINED_ROWS
    WHERE TABLE_NAME = 'ORDER_HIST';
    
    OWNER_NAME  TABLE_NAME  CLUST... HEAD_ROWID          TIMESTAMP
    ----------  ----------  -----... ------------------  ---------
    SCOTT       ORDER_HIST       ... AAAAluAAHAAAAA1AAA  04-MAR-96
    SCOTT       ORDER_HIST       ... AAAAluAAHAAAAA1AAB  04-MAR-96
    SCOTT       ORDER_HIST       ... AAAAluAAHAAAAA1AAC  04-MAR-96
    

    移行行または連鎖行がすべてリストされます。

  3. 出力表の問合せによって、移行行または連鎖行が多数存在することがわかれば、以降のステップを実行して移行行を解消します。
  4. 既存表と同じ列を持つ中間表を作成して、移行行と連鎖行を格納します。
    CREATE TABLE int_order_hist
       AS SELECT *
          FROM order_hist
          WHERE ROWID IN
             (SELECT HEAD_ROWID
                FROM CHAINED_ROWS
                WHERE TABLE_NAME = 'ORDER_HIST');
    
  5. 既存表から移行行と連鎖行を削除します。
    DELETE FROM order_hist
       WHERE ROWID IN
          (SELECT HEAD_ROWID
             FROM CHAINED_ROWS
             WHERE TABLE_NAME = 'ORDER_HIST');
    
  6. 中間表の行を既存表に挿入します。
    INSERT INTO order_hist
       SELECT *
       FROM int_order_hist;
    
  7. 中間表を削除します。
    DROP TABLE int_order_history;
    
  8. ステップ1で収集した情報を出力表から削除します。
    DELETE FROM CHAINED_ROWS
       WHERE TABLE_NAME = 'ORDER_HIST';
    
  9. 再度ANALYZE文を使用してから、出力表を問い合せます。

出力表に表示された行は連鎖しています。連鎖行を解消するには、データ・ブロックのサイズを大きくする以外にありません。すべての状況において連鎖を回避することはほぼ不可能です。多くの場合、LONG列や大きいCHAR列またはVARCHAR2列を持つ表では、連鎖の発生は避けられません。

18.3 表とクラスタの切捨て

表(またはクラスタ)は残したままで、内容が完全に空になるように、表のすべての行またはクラスタ化表のグループ内のすべての行を削除できます。たとえば、月ごとのデータが含まれている表では、各月の終わりにそのデータをアーカイブした後で、表を空にする(すべての行を削除する)必要があります。

18.3.1 DELETEを使用した表の切捨て

DELETEのSQL文を使用して表の行を削除できます。

たとえば、次の文はemp表からすべての行を削除します。

DELETE FROM emp;

DELETE文を使用するときに、表またはクラスタに多数の行が存在していると、それらの行を削除する際に相当のシステム・リソースが使用されます。たとえば、CPU時間、その表と対応付けられた索引のREDOログ領域、UNDOセグメント領域などのリソースが必要です。また、各行が削除されるときに、トリガーが起動される場合があります。結果的に空になる表またはクラスタに事前に割り当てられた領域は、行を削除してもそのオブジェクトに対応付けられたままです。DELETEを使用すると削除する行を選択できますが、TRUNCATEDROPの場合はオブジェクト全体が削除されます。

関連項目:

DELETE文の構文と詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.3.2 DROPおよびCREATEを使用した表の切捨て

表を削除してから、再作成して表を切り捨てることができます。

たとえば、次の例では、emp表を削除してから再作成しています。

DROP TABLE emp;
CREATE TABLE emp ( ... );

表やクラスタを削除してから再作成すると、対応付けられた索引、整合性制約およびトリガーもすべて削除され、削除された表またはクラスタ化表に依存するオブジェクトはすべて無効になります。また、削除された表またはクラスタ化表に対する権限付与もすべて削除されます。

18.3.3 TRUNCATEの使用

TRUNCATE文を使用して表のすべての行を削除できます。

たとえば、次の文はemp表を切り捨てます。

TRUNCATE TABLE emp;

TRUNCATE文を使用すると、表またはクラスタからすべての行を高速かつ効率的に削除できます。TRUNCATE文ではロールバック情報は生成されず、即時にコミットが実行されます。これはDDL文であるため、ロールバックはできません。TRUNCATE文は、切り捨てられる表に関連付けられた構造(制約およびトリガー)または認可には影響を与えません。また、TRUNCATE文では、表を切り捨てた後で、表に現在割り当てられている領域を、その表を含む表領域に戻すかどうかも指定できます。

自分のスキーマにある表またはクラスタは切り捨てることができます。DROP ANY TABLEシステム権限を持っているユーザーは、どのスキーマ内の表またはクラスタでも切り捨てることができます。

親キーを含む表またはクラスタ化表を切り捨てる際は、別の表で定義されているすべての参照外部キーを事前に使用禁止にする必要があります。自己参照制約を使用禁止にする必要はありません。

TRUNCATE文によって表から行を削除する場合、表に対応付けられているトリガーは起動されません。また、TRUNCATE文は、監査が使用可能の場合でも、DELETE文に対応するどのような監査情報も生成しません。そのかわりに、発行されたTRUNCATE文に対して、単一の監査レコードが生成されます。

ハッシュ・クラスタや、ハッシュ・クラスタまたは索引クラスタ内の表を個別に切り捨てることはできません。索引クラスタを切り捨てると、そのクラスタ内のすべての表からすべての行が削除されます。個々のクラスタ化表からすべての行を削除する必要がある場合は、DELETE文を使用するか、または表を削除してから再作成してください。

TRUNCATE文には、表またはクラスタに現在割り当てられている領域が、切捨て後、その表またはクラスタを含む表領域に返されるかどうかを制御するオプションがいくつか用意されています。

これらのオプションは対応する索引にも適用されます。表またはクラスタを切り捨てると、対応付けられた索引もすべて切り捨てられます。切り捨てられた表、クラスタまたは対応付けられた索引の記憶域パラメータは、切捨て後も変わりません。

TRUNCATEのオプションは、次のとおりです。

  • デフォルトのオプションDROP STORAGEは、文実行後の表に割り当てられたエクステントの数をMINEXTENTSの元の設定まで減らします。解放されたエクステントはシステムに戻され、他のオブジェクトによって使用できます。

  • DROP ALL STORAGEは、セグメントを削除します。TRUNCATE TABLE文に加えて、DROP ALL STORAGEALTER TABLE TRUNCATE (SUB)PARTITION文にも適用されます。また、このオプションは切捨て対象のパーティションに対応付けられた依存オブジェクト・セグメントも削除します。

    DROP ALL STORAGEは、クラスタには使用できません。

    TRUNCATE TABLE emp DROP ALL STORAGE;
    
  • REUSE STORAGEを指定すると、表またはクラスタに対して現在割り当てられているすべての領域は割り当てられたままになります。たとえば、次の文はemp_deptクラスタを切り捨てて、クラスタに対してそれまでに割り当てられているすべてのエクステントを、今後の挿入と削除のためにそのまま残します。

    TRUNCATE CLUSTER emp_dept REUSE STORAGE;
    

関連項目:

18.4 トリガーの使用可能および使用禁止

データベース・トリガーとは、データベースに格納されており、表に行を追加するなどの特定の条件が発生したときにアクティブ化(起動)されるプロシージャです。

トリガーを使用してデータベースの標準機能を補完することにより、データベース管理システムを高度にカスタマイズできます。たとえば、表に対するDML操作を制限するトリガーを作成して、通常の営業時間中に発行された文のみ許可できます。

18.4.1 トリガーの使用可能および使用禁止について

トリガーが起動される文を発行したときに、トリガー制限(存在する場合)がTRUEと評価された場合は、使用可能トリガーによってトリガー本体が実行されます。デフォルトでは、トリガーを最初に作成したときに使用可能に設定されます。トリガーが起動される文を発行したときに、トリガー制限(存在する場合)がTRUEと評価された場合でも、使用禁止トリガーはトリガー本体を実行しません。

データベース・トリガーは、表、スキーマまたはデータベースに対応付けることができます。データベース・トリガーは、次の場合に暗黙的に起動されます。

  • 対応付けられている表に対してDML文(INSERTUPDATEDELETE)が実行されたとき

  • データベースまたはスキーマ内のオブジェクトに対して、特定のDDL文(ALTERCREATEDROPなど)が実行されたとき

  • 指定したデータベース・イベントが発生したとき(STARTUPSHUTDOWNSERVERERRORなど)

このリストがすべてではありません。トリガーを起動する文とデータベース・イベントの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

トリガーを作成するには、CREATE TRIGGER文を使用します。トリガーは、トリガー・イベントの前(BEFORE)、後(AFTER)またはトリガー・イベントのかわりに(INSTEAD OF)起動するように定義できます。次の文は、表scott.empに対してトリガーscott.emp_permit_changesを作成します。このトリガーは、指定されたいずれかの文が実行される前に起動します。

CREATE TRIGGER scott.emp_permit_changes
     BEFORE
     DELETE OR INSERT OR UPDATE
     ON scott.emp
     .
     .
     .
pl/sql block 
     .
     .
     .

後でDROP TRIGGER文を発行し、トリガーをデータベースから削除できます。

ALTER TABLE文を使用してトリガーを使用可能または使用禁止にするには、表を所有しているか、表に対するALTERオブジェクト権限があるか、またはALTER ANY TABLEシステム権限があることが必要です。また、ALTER TRIGGER文を使用してトリガーを個別に使用可能または使用禁止にするには、トリガーを所有しているか、またはALTER ANY TRIGGERシステム権限を持っている必要があります。

関連項目:

18.4.2 トリガーを使用可能にする方法

使用禁止のトリガーを使用可能にするには、ENABLEオプションを指定したALTER TRIGGER文を使用します。

たとえば、inventory表に定義されているreorderという使用禁止のトリガーを使用可能にするには、次の文を入力します。

ALTER TRIGGER reorder ENABLE;

ENABLE ALL TRIGGERSオプションを指定したALTER TABLE文を使用すれば、特定の表に定義されているトリガーをすべて使用可能にできます。たとえば、inventory表に定義されているトリガーをすべて使用可能にするには、次の文を入力します。

ALTER TABLE inventory
    ENABLE ALL TRIGGERS;

関連項目:

ALTER TRIGGER文の構文と詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.4.3 トリガーを使用禁止にする方法

トリガーを使用禁止にするには、DISABLEオプションを指定したALTER TRIGGER文を使用します。

次の条件のいずれか1つが成り立つ場合は、一時的にトリガーを使用禁止にすることを検討してください。

  • トリガーの参照するオブジェクトが使用可能でない場合。

  • 大規模なデータ・ロードを実行する際に、トリガーを起動せずに迅速にデータをロードする場合。

  • トリガーが適用される表にデータをロードする場合。

たとえば、inventory表に定義されているトリガーreorderを使用禁止にするには、次の文を入力します。

ALTER TRIGGER reorder DISABLE;

DISABLE ALL TRIGGERSオプションを指定したALTER TABLE文を使用すれば、表に関連するトリガーをすべて同時に使用禁止にできます。たとえば、inventory表に定義されているトリガーをすべて使用禁止にするには、次の文を入力します。

ALTER TABLE inventory
    DISABLE ALL TRIGGERS;

18.5 整合性制約の管理

整合性制約とは、表の1つ以上の列に格納される値を制限するルールです。CREATE TABLE文またはALTER TABLE文に制約句を指定することにより、その制約の影響を受ける列と、制約の条件を識別できます。

関連項目:

18.5.1 整合性制約の状態

整合性制約はビジネス・ルールを適用し、無効な情報が表に入力されるのを防止します。

18.5.1.1 整合性制約の状態について

制約は、使用可能(ENABLE)と使用禁止(DISABLE)のいずれの状態にするかを指定できます。制約が使用可能になっている場合は、データベース内でデータが入力または更新されるときにチェックが行われ、制約に従っていないデータは入力されません。制約が使用禁止になっている場合は、ルールに従っていないデータでもデータベースに入力できます。

また、表の既存データが必ず制約に従うように指定できます(VALIDATE)。逆にNOVALIDATEを指定すると、既存データが制約に従っていることは保証されません。

表に定義されている整合性制約は、次のいずれかの状態にあります。

  • ENABLEVALIDATE

  • ENABLENOVALIDATE

  • DISABLEVALIDATE

  • DISABLENOVALIDATE

これらの状態の意味と組合せの結果の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。これらの結果の一部について説明しています。

18.5.1.2 制約の使用禁止について

整合性制約で定義されたルールを強制するためには、制約が常に使用可能な必要がありますが、状況によっては制約を使用禁止にすることを検討できます。

しかし、次のような場合は、パフォーマンス上の理由から、表の整合性制約を一時的に使用禁止にすることを検討してください。

  • 表に大量のデータをロードする場合

  • 表に大規模な変更を加えるバッチ操作を実行する場合(たとえば、既存の番号に1000を加えてすべての従業員番号を変更する場合)

  • 表を1つずつインポートまたはエクスポートする場合

これら3つの場合には、整合性制約を一時的に使用禁止にすることにより、操作のパフォーマンスを改善できます。これは、特にデータ・ウェアハウス構成に当てはまります。

制約が使用禁止である間は、その制約に違反するデータを入力できます。したがって、前述の操作を終了した後に、制約を必ず使用可能にする必要があります。

18.5.1.3 制約の使用可能について

制約が使用可能になっている場合、制約に違反する行は表に挿入されません。

しかし、制約が使用禁止の場合は、制約に違反する行でも表に挿入できます。このような行を制約の例外と呼びます。制約が妥当性チェックなしで使用可能な状態にある場合、制約が使用禁止になっていた間に入力された違反データはそのまま残っています。制約を妥当性チェック済の状態にするためには、制約に違反する行を更新または削除する必要があります。

制約を使用可能にするときに、特定の整合性制約に対する例外を指定できます。「制約例外のレポート」を参照してください。制約に違反している行はすべてEXCEPTIONS表に格納され、検証できます。

18.5.1.4 妥当性チェックなしで使用可能な制約状態について

制約が妥当性チェックなしで使用可能な状態にある場合、それ以後の文はすべて、制約に従っているかどうかがチェックされます。ただし、表の既存データはチェックされません。

妥当性チェックなしで使用可能な状態の制約を持つ表には、無効なデータが含まれる可能性がありますが、無効なデータを新たに追加することはできません。妥当性チェックなしで使用可能な制約は、有効なオンライン・トランザクション処理(OLTP)データをアップロードしているデータ・ウェアハウス構成で役立ちます。

制約を使用可能にする場合に、妥当性チェックは必ずしも必要ではありません。妥当性チェックなしで制約を使用可能にする方が、妥当性チェックありで制約を使用可能にするよりはるかに高速です。また、すでに使用可能になっている制約の妥当性をチェックする場合、妥当性チェック中のDMLロックは必要ありません(すでに使用禁止にした制約の妥当性をチェックする場合とは異なります)。これは、制約の規定により、妥当性チェック中に違反データが挿入されないことが保証されているためです。したがって、妥当性チェックなしで使用可能にすれば、制約を使用可能にすることによって一般に生じる停止時間を短縮できます。

18.5.1.5 整合性制約の効率的な使用: 手順

整合性制約の状態を特定の順序で使用することが重要です。

整合性制約の状態を次の順序で使用したときに、最も大きな利点が得られます。

  1. 使用禁止状態。
  2. 操作(ロード、エクスポート、インポート)の実行。
  3. 妥当性チェックなしで使用可能な状態。
  4. 使用可能状態。

制約をこの順序で使用する際の利点は、次のとおりです。

  • ロックが保持されません。

  • すべての制約を同時に使用可能状態にすることができます。

  • 制約を使用可能にする処理がパラレルで行われます。

  • 表での同時アクティビティを実行できます。

18.5.2 定義時の整合性制約の設定

CREATE TABLE文またはALTER TABLE文で整合性制約を定義するときにENABLE/DISABLE句を指定して、その制約を使用可能/使用禁止、妥当性チェックあり/妥当性チェックなしの状態にできます。制約の定義時にENABLE/DISABLE句を指定しなければ、自動的にその制約は妥当性チェックありで使用可能な状態になります。

18.5.2.1 定義時に制約を使用禁止にする方法

定義時に整合性制約を使用禁止にできます。

次のCREATE TABLE文とALTER TABLE文は、整合性制約を定義して、使用禁止にします。

CREATE TABLE emp (
    empno NUMBER(5) PRIMARY KEY DISABLE,   . . . ;

ALTER TABLE emp
   ADD PRIMARY KEY (empno) DISABLE;

整合性制約を定義して使用禁止にするALTER TABLE文は、表の行がその整合性制約に違反しているために失敗することはありません。制約のルールが施行されていないので、制約の定義が許可されます。

18.5.2.2 定義時に制約を使用可能にする方法

定義時に整合性制約を使用可能にできます。

次のCREATE TABLE文とALTER TABLE文は、整合性制約を定義して、使用可能にします。

CREATE TABLE emp (
    empno NUMBER(5) CONSTRAINT emp.pk PRIMARY KEY,   . . . ;

ALTER TABLE emp
    ADD CONSTRAINT emp.pk PRIMARY KEY (empno);

整合性制約を定義して使用可能にするALTER TABLE文は、表の行が整合性制約に違反しているために失敗する場合があります。この場合、その文はロールバックされ、制約定義は格納されず、使用可能にもなりません。

UNIQUEまたはPRIMARY KEY制約を使用可能にすると、対応する索引が作成されます。

ノート:

並列性を利用できるように制約を使用可能にする効率的な手順は、「整合性制約の効率的な使用: 手順」を参照してください。

18.5.3 既存の整合性制約の変更、名前変更または削除

ALTER TABLE文では、制約を使用可能または使用禁止にする他、制約を変更または削除することもできます。制約を規定するためにUNIQUEまたはPRIMARY KEY索引が使用されている場合、その索引に対応する制約を削除または使用禁止にすると、明示的に指定しないかぎり、索引は削除されます。

使用可能な外部キーが主キーまたは一意キーを参照している間は、主キー制約または一意キー制約、または索引を使用禁止にしたり削除することはできません。

18.5.3.1 制約の使用禁止および使用可能

使用可能な整合性制約を使用禁止にし、使用禁止の整合性制約を使用可能にできます。

次の文は、使用可能状態の整合性制約を使用禁止にします。2番目の文では、対応する索引を保持するように指定しています。

ALTER TABLE dept
    DISABLE CONSTRAINT dname_ukey;

ALTER TABLE dept
    DISABLE PRIMARY KEY KEEP INDEX,
    DISABLE UNIQUE (dname, loc) KEEP INDEX;

次の文は、使用禁止状態の整合性制約を妥当性チェックなしで使用可能な状態にします。

ALTER TABLE dept
    ENABLE NOVALIDATE CONSTRAINT dname_ukey;

ALTER TABLE dept
    ENABLE NOVALIDATE PRIMARY KEY,
    ENABLE NOVALIDATE UNIQUE (dname, loc);

次の文は、使用禁止状態の整合性制約を使用可能にするか、または妥当性チェックありの状態にします。

ALTER TABLE dept
    MODIFY CONSTRAINT dname_key VALIDATE;

ALTER TABLE dept
    MODIFY PRIMARY KEY ENABLE NOVALIDATE;

次の文は、使用禁止状態の整合性制約を使用可能にします。

ALTER TABLE dept
    ENABLE CONSTRAINT dname_ukey;

ALTER TABLE dept
    ENABLE PRIMARY KEY,
    ENABLE UNIQUE (dname, loc);

UNIQUEキーまたはPRIMARY KEY制約、およびすべての依存するFOREIGN KEY制約を一度に使用禁止または削除するには、DISABLE句またはDROP句のCASCADEオプションを使用します。たとえば、次の文はPRIMARY KEY制約とこれに依存するFOREIGN KEY制約を使用禁止にします。

ALTER TABLE dept
    DISABLE PRIMARY KEY CASCADE;
18.5.3.2 制約名の変更

ALTER TABLE...RENAME CONSTRAINT文を使用すると、表に対する既存の制約の名前を変更できます。新しい制約名には、ユーザーの既存の制約名と競合しない名前を指定する必要があります。

次の文は、表deptに対するdname_ukey制約の名前を変更します。

ALTER TABLE dept
    RENAME CONSTRAINT dname_ukey TO dname_unikey;

制約名を変更しても、実表に対するすべての依存性は引き続き有効です。

RENAME CONSTRAINT句を使用すると、制約のシステム生成名を変更できます。

18.5.3.3 制約の削除

整合性制約は、規定するルールが成立しなくなった場合、またはその制約が不要になった場合に削除できます。

制約を削除するには、ALTER TABLE文で次のいずれかの句を指定します。

  • DROP PRIMARY KEY

  • DROP UNIQUE

  • DROP CONSTRAINT

次の2つの文は、整合性制約を削除します。2番目の文は、PRIMARY KEY制約に対応する索引を保持します。

ALTER TABLE dept
    DROP UNIQUE (dname, loc);

ALTER TABLE emp
    DROP PRIMARY KEY KEEP INDEX
    DROP CONSTRAINT dept_fkey;

FOREIGN KEYUNIQUEまたはPRIMARY KEYを参照している場合は、DROP文にCASCADE CONSTRAINTS句を指定しないかぎり、制約を削除できません。

18.5.4 制約チェックの遅延

データベースが制約をチェックしたときに制約が満たされていない場合は、エラーが通知されます。制約の妥当性チェックは、トランザクションが終わるまで遅延できます。SET CONSTRAINTS文を発行すると、トランザクションの実行中、または別のSET CONSTRAINTS文によってモードが再設定されるまで、SET CONSTRAINTSモードが継続します。

ノート:

  • SET CONSTRAINT文は、トリガーの内部では発行できません。

  • 遅延可能な一意キーと主キーは、必ず非一意索引を使用する必要があります。

18.5.4.1 すべての制約を遅延に設定する方法

トランザクションの制約を遅延する必要がある場合、データ操作に使用するアプリケーションでは、実際にデータの処理を始める前にすべての制約を遅延に設定する必要があります。

遅延可能制約をすべて遅延に設定するには、次のDML文を使用します。

SET CONSTRAINTS ALL DEFERRED; 

ノート:

SET CONSTRAINTS文は、現行のトランザクションにのみ適用されます。制約を作成したときに指定したデフォルトは、その制約が存在するかぎり保持されています。ALTER SESSION SET CONSTRAINTS文は、現行のセッションにしか適用されません。

18.5.4.2 コミットのチェック(オプション)

COMMITの発行直前にSET CONSTRAINTS ALL IMMEDIATE文を発行することにより、制約違反をチェックできます。

制約になんらかの問題があると、この文は失敗し、エラーの原因となっている制約が識別されます。制約違反のままコミットすると、トランザクションはロールバックされ、エラー・メッセージが返されます。

18.5.5 制約例外のレポート

制約の妥当性チェック時に例外が存在すると、エラーが返され、整合性制約は妥当性チェックなしの状態のままになります。整合性制約の例外が存在しているために文が正常に実行されない場合、文はロールバックされます。例外が存在している場合は、制約の例外をすべて更新または削除するまで、制約の妥当性はチェックできません。

整合性制約に違反している行を判断するには、ENABLE句にEXCEPTIONSオプションを指定してALTER TABLE文を発行します。EXCEPTIONSオプションにより、例外を含むすべての行の行ID、表所有者、表名および制約名が指定した表に格納されます。

制約を使用可能にする前に、ENABLE句のEXCEPTIONSオプションからの情報を格納する適切な例外レポート表を作成する必要があります。例外表を作成するには、UTLEXCPT.SQLスクリプトまたはUTLEXPT1.SQLスクリプトを実行します。

ノート:

EXCEPTIONS表を作成するためにどちらのスクリプトを実行するかは、分析する表のタイプによって決まります。詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

これらのスクリプトのどちらを使用しても、EXCEPTIONSという名前の表が作成されます。また、スクリプトを変更して再実行すると、新たに別の名前の例外表を作成できます。

次の文は、dept表のPRIMARY KEYを検証します。例外が存在すると、EXCEPTIONS表に情報が挿入されます。

ALTER TABLE dept ENABLE PRIMARY KEY EXCEPTIONS INTO EXCEPTIONS;

dept表に重複する主キー値が存在し、deptPRIMARY KEY制約の名前がsys_c00610である場合は、次の問合せによって例外が表示されます。

SELECT * FROM EXCEPTIONS;

次の例外が表示されます。

fROWID               OWNER      TABLE_NAME      CONSTRAINT
------------------  ---------  --------------  -----------
AAAAZ9AABAAABvqAAB  SCOTT      DEPT            SYS_C00610 
AAAAZ9AABAAABvqAAG  SCOTT      DEPT            SYS_C00610 

次の文および結果のように、例外レポート表およびマスター表の行を結合した詳細な問合せの実行により、特定の制約に違反している実際の行を表示できます。

SELECT deptno, dname, loc FROM dept, EXCEPTIONS
    WHERE EXCEPTIONS.constraint = 'SYS_C00610'
    AND dept.rowid = EXCEPTIONS.row_id;

DEPTNO     DNAME             LOC
---------- --------------    -----------
10         ACCOUNTING        NEW YORK
10         RESEARCH          DALLAS

制約に違反している行はすべて更新するか、または制約を含む表から削除する必要があります。例外を更新する場合は、制約に違反する値を、制約を満たす値またはNULLに変更します。マスター表の行を更新または削除した後、以後取得する例外レポートとの混同を避けるために、例外レポート表の例外に対応する行は削除します。マスター表と例外レポート表を更新する文は、トランザクションの一貫性を保証するために、同じトランザクション内で実行してください。

前述の例の例外を訂正するために、次のトランザクションを発行できます。

UPDATE dept SET deptno = 20 WHERE dname = 'RESEARCH';
DELETE FROM EXCEPTIONS WHERE constraint = 'SYS_C00610';
COMMIT;

例外管理の最終的な目的は、例外レポート表の例外をすべて取り除くことにあります。

ノート:

制約が使用禁止になっている表の現在の例外を訂正している間に、他のユーザーが新しい例外を作成する文を発行する可能性があります。これを避けるには、例外を取り除く前に、制約にENABLE NOVALIDATEのマークを付けます。

関連項目:

EXCEPTIONS表の詳細は、『Oracle Databaseリファレンス』を参照してください。

18.5.6 制約情報の表示

表の制約定義を表示し、制約で指定されている列を識別できるように、ビューのセットが用意されています。

ビュー 説明

DBA_CONSTRAINTS

ALL_CONSTRAINTS

USER_CONSTRAINTS

DBAビューには、データベース内のすべての制約定義が表示されます。ALLビューには、現行ユーザーがアクセス可能な制約定義が表示されます。USERビューには、現行ユーザーが所有している制約定義が表示されます。

DBA_CONS_COLUMNS

ALL_CONS_COLUMNS

USER_CONS_COLUMNS

DBAビューには、制約で指定されているデータベース内のすべての列が表示されます。ALLビューには、制約で指定されていて、現行ユーザーがアクセス可能な列のみが表示されます。USERビューには、制約で指定されていて、現行ユーザーが所有している列のみが表示されます。

関連項目:

18.6 スキーマ・オブジェクトの名前変更

オブジェクト名は複数の方法で変更できます。

オブジェクト名を変更するには、そのオブジェクトが自分のスキーマ内に存在する必要があります。スキーマ・オブジェクトは、次のいずれかの方法で名前を変更できます。

  • オブジェクトを削除して再作成する。

  • RENAME文を使用してオブジェクトの名前を変更する。

  • ALTER ... RENAME文を使用してオブジェクトの名前を変更する(索引およびトリガーの場合)。

オブジェクトを削除して再作成する場合、そのオブジェクトに付与された権限はすべて失われます。オブジェクトを再作成するときに、再度権限を付与してください。

RENAME文を使用して、表、ビュー、順序またはそれらのプライベート・シノニムの名前を変更することもできます。RENAME文を使用すると、そのオブジェクトの整合性制約、索引および権限付与は新しい名前に引き継がれます。たとえば、次の文はsales_staffビューの名前を変更します。

RENAME sales_staff TO dept_30;  

ノート:

ストアドPL/SQLプログラム・ユニット、パブリック・シノニムまたはクラスタに対しては、RENAMEを使用できません。これらのオブジェクトの名前を変更するには、削除してから再作成してください。

スキーマ・オブジェクト名を変更する前に、次のような影響について検討する必要があります。

  • 名前を変更されたオブジェクトに依存しているビューとPL/SQLプログラム・ユニットはすべて無効になるため、次に使用する前に再コンパイルする必要があります。

  • 名前を変更されたオブジェクトのシノニムを使用すると、必ずエラーが返されます。

    関連項目:

    RENAME文の構文は、『Oracle Database SQL言語リファレンス』を参照してください。

18.7 オブジェクト依存性の管理

Oracle Databaseには、依存オブジェクトが参照オブジェクトに関して常に最新であることを確認する自動メカニズムが用意されています。無効なオブジェクトを手動で再コンパイルすることもできます。

18.7.1 オブジェクト依存性とオブジェクトの無効化について

スキーマ・オブジェクトには、他のオブジェクトを参照するタイプのものがあります。他のオブジェクトを参照するオブジェクトは依存オブジェクトと呼ばれ、参照されるオブジェクトは参照オブジェクトと呼ばれます。これらの参照はコンパイル時に確立され、コンパイラで解決できない場合は、コンパイル中の依存オブジェクトが「無効」とマークされます。

たとえば、ビューには表または他のビューを参照する問合せが含まれ、PL/SQLサブプログラムは他のサブプログラムを起動し、静的SQLを使用して表やビューを参照します。

Oracle Databaseには、依存オブジェクトが参照オブジェクトに関して常に最新であることを確認する自動メカニズムが用意されています。依存オブジェクトが作成されると、データベースによって、依存オブジェクトとその参照オブジェクト間の依存性が追跡されます。参照オブジェクトが依存オブジェクトに影響を与えるような方法で変更されると、依存オブジェクトには無効のマークが付けられます。無効になった依存オブジェクトは、参照オブジェクトの新しい定義で再コンパイルして使用できるようにする必要があります。再コンパイルは、無効な依存オブジェクトが参照されると自動的に実行されます。

無効化はデータベース上で稼働するアプリケーションに影響を及ぼすため、スキーマ・オブジェクトを無効化する可能性がある変更を理解しておくことが重要です。ここでは、オブジェクトが無効になる仕組み、無効なオブジェクトを識別する方法、および無効なオブジェクトの妥当性をチェックする方法について説明します。

オブジェクトの無効化

通常、正常に実行中のアプリケーションでは表構造の変更やビュー定義またはストアド・プロシージャ定義の変更は行われないため、標準的な稼働中アプリケーションでビューやストアド・プロシージャが無効になることは予期されていません。表、ビューまたはPL/SQLユニットへの変更は、パッチ・スクリプトまたは非定型DDL文を使用してアプリケーションにパッチを適用するとき、またはアップグレードするときに発生するのが一般的です。パッチが適用されて参照オブジェクトのセットが変更された後、依存オブジェクトが無効のまま残る場合があります。

データベース内の無効な一連のオブジェクトを表示するには、次の問合せを使用します。

SELECT object_name, object_type FROM dba_objects
WHERE status = 'INVALID';

スキーマ・オブジェクトが無効になると、Oracle Enterprise Manager Cloud Controlのデータベース・ホームページにアラートが表示されます。

オブジェクトの無効化によって、アプリケーションは次の2つの影響を受けます。第1に、無効なオブジェクトは、再検証されるまでアプリケーションで使用できません。再検証によって、アプリケーション実行の待機時間が長くなります。無効なオブジェクトが多数ある場合は、初回実行時の待機時間が長時間になる可能性があります。第2に、プロシージャ、ファンクションまたはパッケージの無効化によって、そのプロシージャ、ファンクションまたはパッケージを同時に実行している他のセッションで例外が発生する可能性があります。アプリケーションを別のセッションで使用しているときにパッチを適用すると、アプリケーションを実行しているセッションによって、使用中のオブジェクトが無効化されたことが通知され、ORA-04061、ORA-04064、ORA-04065またはORA-04068の4つの例外のうちのいずれか1つが発生します。これらの例外は、パッチ適用後にアプリケーション・セッションを再起動して修正する必要があります。

適切なSQL文にCOMPILE句を指定して、スキーマ・オブジェクトを強制的に再コンパイルできます。詳細は、「DDLを使用した手動による無効なオブジェクトの再コンパイル」を参照してください。

無効なオブジェクトが多数存在することが判明している場合は、UTL_RECOMP PL/SQLパッケージを使用して一括再コンパイルを実行します。詳細は、「PL/SQLパッケージのプロシージャを使用した手動による無効なオブジェクトの再コンパイル」を参照してください。

次に、スキーマ・オブジェクトの無効化に関する一般的な規則をいくつか示します。

  • 参照オブジェクトとその依存オブジェクトの間で、データベースは、依存関係に含まれる参照オブジェクトの要素を追跡します。たとえば、単一表のビューで表内の列のサブセットのみが選択された場合、それらの列のみが依存関係に含まれます。オブジェクトの各依存関係について、依存関係に含まれる要素の定義が変更されると(要素の削除も含む)、依存オブジェクトは無効になります。逆に、依存関係に含まれない要素の定義のみが変更された場合、依存オブジェクトは有効なままです。

    したがって、開発者がスキーマ・オブジェクトの変更時に注意することにより、多くの場合、依存オブジェクトの無効化とそれによるデータベースへの不要な追加作業の発生を回避できます。

  • 依存オブジェクトは連鎖的に無効になります。オブジェクトがなんらかの理由で無効になると、そのオブジェクトのすべての依存オブジェクトがただちに無効になります。

  • スキーマ・オブジェクトに対するオブジェクト権限を取り消すと、依存オブジェクトは連鎖的に無効になります。

関連項目:

スキーマ・オブジェクトの依存性の詳細は、『Oracle Database概要』を参照してください。

18.7.2 DDLを使用した手動による無効なオブジェクトの再コンパイル

単一のスキーマ・オブジェクトを手動で再コンパイルするには、ALTER文を使用します。

たとえば、パッケージ本体のPkg1を再コンパイルするには、次のDDL文を実行します。

ALTER PACKAGE pkg1 COMPILE REUSE SETTINGS;

関連項目:

様々なALTER文の構文と詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

18.7.3 PL/SQLパッケージのプロシージャを使用した手動による無効なオブジェクトの再コンパイル

RECOMP_SERIALプロシージャは、スキーマ名引数が指定されない場合、指定されたスキーマのすべての無効なオブジェクト、またはデータベース内のすべての無効なオブジェクトを再コンパイルします。RECOMP_PARALLELプロシージャも同様ですが、複数のCPUをパラレルに使用します。

アプリケーションのアップグレードまたはパッチの適用に続いて、無効なオブジェクトを再検証して、オンデマンドのオブジェクト再検証で生じるアプリケーションの待ち時間を回避することをお薦めします。Oracleには、オブジェクトの再検証で役立つUTL_RECOMPパッケージが用意されています。

次のPL/SQLブロックを実行して、データベース内の無効なオブジェクトすべてをパラレルに、依存順序に従って再検証します。

begin
   utl_recomp.recomp_parallel();
end;
/

DBMS_UTILITYパッケージを使用して、無効なオブジェクトを個別に再検証することもできます。次のスクリプトは、HRスキーマのUPDATE_SALARYプロシージャを再検証するPL/SQLブロックです。

begin
   dbms_utility.validate('HR', 'UPDATE_SALARY', namespace=>1);
end;
/

次のスクリプトは、パッケージ本体のHR.ACCT_MGMTを再検証するPL/SQLブロックです。

begin
   dbms_utility.validate('HR', 'ACCT_MGMT', namespace=>2);
end;
/

関連項目:

18.8 オブジェクトの名前解決の管理

SQL文で参照されるオブジェクト名は、ピリオドで区切られた複数の断片から構成できます。Oracle Databaseはオブジェクト名を解決するために特定の処理を実行します。

ここでは、データベースでオブジェクト名を解決する方法を説明します。

  1. Oracle Databaseは、SQL文で参照される名前の最初の断片を識別しようとします。たとえば、scott.empの最初の断片はscottです。断片が1つしか存在しない場合、その断片は最初の断片とみなされます。

    1. 現行スキーマ内で、オブジェクト名の最初の断片に一致するオブジェクトが検索されます。このようなオブジェクトが見つからない場合は、ステップ1.bに進みます。

    2. オブジェクト名の最初の断片に一致するパブリック・シノニムが検索されます。このようなパブリック・シノニムが見つからない場合は、ステップ1.cに進みます。

    3. データベースでは、オブジェクト名の最初の断片に一致するスキーマが検索されます。一致が見つかると、そのスキーマは完全修飾スキーマとなり、ステップ1.dに進みます。

      ステップ1.cでスキーマが見つからない場合、オブジェクトは識別されず、データベースからエラーが返されます。

    4. 完全修飾スキーマ内で、オブジェクト名の2番目の断片に一致するオブジェクトが検索されます。

      2番目の断片が、前回識別されたスキーマ内のオブジェクトに対応しない場合、または2番目の断片がない場合は、データベースはエラーを返します。

  2. スキーマ・オブジェクトは修飾されています。名前の残りの断片は、見つかったオブジェクトの有効な部分に一致する必要があります。たとえば、名前がscott.emp.deptnoで、scottがスキーマとして識別され、empが表として識別された場合は、(empが表であるため)deptnoは列に対応する必要があります。また、empがパッケージとして識別された場合、deptnoはそのパッケージのパブリック定数、変数、プロシージャまたはファンクションに対応する必要があります。

分散データベースにおいて、グローバル・オブジェクト名が明示的またはシノニム内で間接的に使用されている場合、ローカル・データベースはローカルで参照を解決します。たとえば、シノニムをリモート表のグローバル・オブジェクト名として解決します。部分的に解決された文はリモート・データベースに転送され、前述の手順に従って、リモート・データベースでオブジェクトの解決が行われます。

データベースによる参照の解決方法の関係で、あるオブジェクトが、他のオブジェクトが存在しないことに依存している可能性があります。この状況が発生するのは、依存するオブジェクトが使用している参照の解析方法が、他のオブジェクトが存在しているときには異なる場合です。たとえば、次のような場合を考えてみます。

  • 現時点では、companyスキーマに表empが含まれています。

  • company.empに対してPUBLICシノニムempが作成され、company.empに対するSELECT権限がPUBLICロールに付与されます。

  • jwardスキーマには、表またはプライベート・シノニムempは含まれていません。

  • ユーザーjwardが、次の文を使用して自分のスキーマにビューを作成します。

    CREATE VIEW dept_salaries AS 
         SELECT deptno, MIN(sal), AVG(sal), MAX(sal) FROM emp 
         GROUP BY deptno 
         ORDER BY deptno; 
    

jwarddept_salariesビューを作成すると、empへの参照は、jward.empを表、ビューまたはプライベート・シノニムとして検索し、いずれも見つからない場合はパブリック・シノニムempとして検索して見つけることで解決されます。その結果、jward.dept_salariesは、jward.empが存在しないことと、public.empが存在することに依存していることがわかります。

ここで、jwardが次の文を使用して自分のスキーマに新しいビューempを作成するとします。

CREATE VIEW emp AS 
     SELECT empno, ename, mgr, deptno 
     FROM company.emp; 

jward.empの構造がcompany.empとは異なることに注意してください。

データベースは、オブジェクト定義内の参照を解決しようとする際に、新規の依存オブジェクトの、「存在しない」オブジェクト(存在していたとすると、オブジェクトの定義の解析を変えてしまうスキーマ・オブジェクト)への依存性に内部的に注目します。存在しないオブジェクトを後で作成する場合は、このような依存性に注意する必要があります。存在しないオブジェクトを作成する場合、依存オブジェクトを再コンパイルおよび検証できるようにすべての依存オブジェクトを無効化するとともに、依存するすべてのファンクション索引に使用禁止とマークする必要があります。

したがって、前述の例では、jward.empが作成されると、jward.dept_salariesjward.empに依存するため無効になります。その後、jward.dept_salariesが使用されると、データベースはビューの再コンパイルを試みます。empへの参照を解決するときに、jward.empが見つかります(public.empは参照先のオブジェクトではなくなっています)。jward.empにはsal列がないため、ビューを置換するときにエラーが見つかり、ビューは無効のままになります。

要約すると、存在しないオブジェクトを後で作成する場合は、オブジェクトの解決中にチェックされる存在しないオブジェクトへの依存性を管理する必要があります。

関連項目:

分散データベースにおける名前解決の詳細は、「スキーマ・オブジェクトとデータベース・リンク」を参照してください

18.9 異なるスキーマへの切替え

ALTER SESSIONのSQL文を使用して別のスキーマに切り替えることができます。

次の文は、現行セッションのスキーマを、この文で指定するスキーマ名に設定します。

ALTER SESSION SET CURRENT_SCHEMA = <schema name>

その後のSQL文では、修飾子が省略されている場合に、Oracle Databaseによって、このスキーマ名がスキーマ修飾子として使用されます。また、データベースでは、指定したスキーマの一時表領域が、一時データベース・オブジェクトのソート、結合および格納に使用されます。セッションには元の権限が保持され、前述のALTER SESSION文によって余分な権限は取得されません。

次の例では、プロンプトが表示されたらパスワードを入力します。

CONNECT scott
ALTER SESSION SET CURRENT_SCHEMA = joe;
SELECT * FROM emp;

empは識別されたスキーマではないため、表名はjoeスキーマのもとで解決されます。ただし、scottjoe.emp表の選択権限を持たない場合、scottSELECT文を実行できません。

18.10 エディションの管理

エディションに基づく再定義によりアプリケーションをアップグレードするアプリケーション開発者が、DBA権限を必要とするエディション関連のタスクを実行するように要求する場合があります。

18.10.1 エディションおよびエディションに基づく再定義について

エディションベースの再定義を使用すると、アプリケーションの使用中にアプリケーションのデータベース・オブジェクトをアップグレードできるため、停止時間を最小限に抑えることや解消することが可能です。これは、エディションと呼ばれるプライベート環境でデータベース・オブジェクトを変更(再定義)することによって実行します。

すべての変更が実行およびテストされている場合のみ、アプリケーションの新バージョンをユーザーが使用できるようにしてください。

関連項目:

エディションに基づく再定義の詳細な説明は、『Oracle Database開発ガイド』を参照してください。

18.10.2 エディションに基づく再定義のためのDBAのタスク

エディションに基づく再定義に関連するタスクを行うには、ユーザーが必要な権限を持っている必要があります。

表18-1に、通常はDBAにのみ付与される権限を必要とするエディション関連のタスクの要約を示します。DBAのロールを付与されているユーザーはこれらのタスクを実行可能です。

表18-1 エディションに基づく再定義のためのDBAのタスク

タスク 参照

エディションを作成、変更、および削除する権限の付与または取消し

CREATE EDITIONおよびDROP EDITION SQL文

スキーマのエディションの有効化

『Oracle Database開発ガイド』

データベースのデフォルト・エディションの設定

「データベースのデフォルトのエディションの設定」

データベース・サービスのエディション属性を設定します。

「データベース・サービスのエディション属性の設定」

18.10.3 データベースのデフォルトのエディションの設定

データベースには必ずデフォルトのエディションがあります。これは、接続時にエディションが明示的に示されない場合にデータベース・セッションが最初に使用するエディションです。

データベースのデフォルト・エディションを設定するには:

  1. データベースにALTER DATABASE権限とエディションに対するUSE権限WITH GRANT OPTIONを持つユーザーとして接続します。

  2. 次の文を入力します。

    ALTER DATABASE DEFAULT EDITION = edition_name;

18.10.4 データベースのデフォルト・エディションの問合せ

データベースのデフォルト・エディションは、データベースのプロパティとして格納されています。

データベースのデフォルト・エディションを問い合せるには:

  1. 任意のユーザーとしてデータベースに接続します。

  2. 次の文を入力します。

    SELECT PROPERTY_VALUE FROM DATABASE_PROPERTIES WHERE 
       PROPERTY_NAME = 'DEFAULT_EDITION';
    
    PROPERTY_VALUE
    ------------------------------
    ORA$BASE

ノート:

プロパティ名のDEFAULT_EDITIONは大文字/小文字が区別されます。必ず大文字で入力してください。

18.10.5 データベース・サービスのエディション属性の設定

データベース・サービスの作成時にそのエディション属性を設定したり、既存のデータベース・サービスのエディション属性を変更できます。

ノート:

インスタンスのデータベース・サービスの数には、上限があります。この制限の詳細は、『Oracle Databaseリファレンス』を参照してください。

18.10.5.1 データベース・サービスのエディション属性の設定について

サービスのエディション属性を設定すると、クライアント接続やDBMS_SCHEDULERジョブなどサービスを指定する後続のすべての接続はこのエディションを初期セッション・エディションとして使用します。ただし、セッション接続に別のエディションが指定されている場合は、セッション接続に指定されているエディションがセッション・エディションに使用されます。

データベース・サービスのエディション属性をチェックするには、ALL_SERVICESビューまたはDBA_SERVICESビューのEDITION列に問い合せます。

18.10.5.2 データベース・サービス作成時のエディション属性の設定

RVCTLユーティリティまたはDBMS_SERVICEパッケージを使用して、サービスの作成時にデータベース・サービスのエディション属性を設定できます。

データベース・サービスのエディション属性を設定するには、「データベース・サービスの作成」の手順に従い、適切なオプションを使用します。

  • 単一インスタンス・データベースをOracle Restartで管理している場合は、SRVCTLユーティリティを使用してデータベース・サービスを作成し、-editionオプションを指定してそのエディション属性を設定します。

    この例では、DB_UNIQUE_NAMEdbcrmであるデータベースを対象に、crmbatchという名前で新規データベース・サービスを作成し、データベース・サービスのエディション属性をe2に設定します。

    srvctl add service -db dbcrm -service crmbatch -edition e2
    
  • 単一インスタンス・データベースをOracle Restartで管理していない場合は、DBMS_SERVICE.CREATE_SERVICEプロシージャを使用し、editionパラメータを指定してデータベース・サービスのエディション属性を設定します。

18.10.5.3 既存のデータベース・サービスのエディション属性の設定

既存のデータベース・サービスのエディション属性を設定するには、SRVCTLユーティリティまたはDBMS_SERVICEパッケージを使用します。

既存のデータベース・サービスのエディション属性を設定するには:

  1. データベース・サービスを停止します。

  2. 適切なオプションを使用して、データベース・サービスのエディション属性を設定します。

    • 単一インスタンス・データベースをOracle Restartで管理している場合は、SRVCTLユーティリティを使用してデータベース・サービスを変更し、-editionオプションを指定してそのエディション属性を設定します。

      この例では、DB_UNIQUE_NAMEdbcrmであるデータベースを対象に、crmbatchという名前のデータベース・サービスを変更し、データベース・サービスのエディション属性をe3に設定します。

      srvctl modify service -db dbcrm -service crmbatch -edition e3
      
    • 単一インスタンス・データベースをOracle Restartで管理していない場合は、DBMS_SERVICE.MODIFY_SERVICEプロシージャを使用し、editionパラメータを指定してデータベース・サービスのエディション属性を設定します。MODIFY_SERVICEプロシージャを実行するときには、modify_editionパラメータがTRUEに設定されていることを確認してください。

  3. データベース・サービスを起動します。

関連項目:

18.10.6 エディションの使用

特定のエディションのオブジェクトを表示または変更するには、最初にそのエディションを使用する必要があります。データベースに接続したときに、使用するエディションを指定できます。エディションを指定しない場合は、データベースのデフォルトのエディションでセッションが開始されます。

異なるエディションを使用するには、次の文を発行します。

ALTER SESSION SET EDITION=edition_name;

次の文は、現在のエディションをe2に設定してから、ora$baseに設定します。

ALTER SESSION SET EDITION=e2;
...
ALTER SESSION SET EDITION=ora$base;

関連項目:

18.10.7 エディションのデータ・ディクショナリ・ビュー

エディションの管理に役立つデータ・ディクショナリ・ビューがいくつかあります。

次の表に、そのうちの3つを示します。完全なリストは、『Oracle Database開発ガイド』を参照してください。

ビュー 説明

*_EDITIONS

データベース内のすべてのエディションがリストされます。(ノート: USER_EDITIONSは存在しません。)

*_OBJECTS

現在のエディションで表示可能な(実在するか、継承されている)データベースのすべてのオブジェクトを示します。

*_OBJECTS_AE

エディション全体のデータベース内にあるすべての実在のオブジェクトを示します。

18.11 スキーマ・オブジェクト情報の表示

Oracle DatabaseにはPL/SQLパッケージが用意されており、スキーマ・オブジェクト情報の表示に使用できるオブジェクトおよびデータ・ディクショナリ・ビューを作成したDDLを判断できます。

18.11.1 PL/SQLパッケージを使用したスキーマ・オブジェクト情報の表示

オラクル社が提供するPL/SQLパッケージDBMS_METADATA.GET_DDLを使用すると、スキーマ・オブジェクトに関するメタデータを(オブジェクトの作成に使用するDDLの形式で)取得できます。

関連項目:

DBMS_METADATAパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

例: DBMS_METADATAパッケージの使用

DBMS_METADATAパッケージは、スキーマ・オブジェクトの完全な定義を取得するための強力なツールです。これにより、あるオブジェクトのすべての属性を1回のパスで取得できます。オブジェクトは、その作成(再作成)に使用できるDDLで表されます。

次の文では、GET_DDLファンクションを使用して、現行スキーマ内にあるすべての表のDDLをフェッチし、ネストした表とオーバーフロー・セグメントを除外しています。また、SQL DDLで記憶域句が返されないようにするため、SET_TRANSFORM_PARAM(ハンドル値として「現行セッション用」を意味するDBMS_METADATA.SESSION_TRANSFORMをとる)を使用してそれを指定しています。セッション・レベルの変換パラメータは、最後にデフォルトにリセットされています。変換パラメータ値は、いったん設定すると、明示的にデフォルトにリセットされるまで有効です。

EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(
     DBMS_METADATA.SESSION_TRANSFORM,'STORAGE',false);
SELECT DBMS_METADATA.GET_DDL('TABLE',u.table_name)
     FROM USER_ALL_TABLES u
     WHERE u.nested='NO' 
     AND (u.iot_type is null or u.iot_type='IOT');
EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(
     DBMS_METADATA.SESSION_TRANSFORM,'DEFAULT');

DBMS_METADATA.GET_DDLからの出力はLONGデータ型です。SQL*Plusを使用している場合は、出力がデフォルトで切り捨てられる場合があります。出力が切り捨てられないようにするには、DBMS_METADATA.GET_DDL文を発行する前に、次のSQL*Plusコマンドを発行してください。

SQL> SET LONG 9999

18.11.2 スキーマ・オブジェクトのデータ・ディクショナリ・ビュー

次のビューには、スキーマ・オブジェクトに関する一般的な情報が表示されます。

ビュー 説明

DBA_OBJECTS

ALL_OBJECTS

USER_OBJECTS

DBAビューには、データベース内のすべてのスキーマ・オブジェクトが表示されます。ALLビューには、現行ユーザーがアクセス可能なオブジェクトが表示されます。USERビューには、現行ユーザーが所有しているオブジェクトが表示されます。

DBA_CATALOG

ALL_CATALOG

USER_CATALOG

データベース内にあるすべての表、ビュー、シノニムおよび順序の名前、タイプおよび所有者(USERビューでは所有者は表示されない)がリストされます。

DBA_DEPENDENCIES

ALL_DEPENDENCIES

USER_DEPENDENCIES

プロシージャ、パッケージ、ファンクション、パッケージ本体およびトリガーの間の依存性(データベース・リンクを持たないビューへの依存性など)がすべてリストされます。

18.11.2.1 例1: スキーマ・オブジェクトのタイプ別表示

USER_OBJECTSビューに対する問合せを実行して、問合せを発行したユーザーが所有するすべてのオブジェクトのリストを表示できます。

次の問合せは、問合せを発行しているユーザーが所有しているオブジェクトをすべてリストします。

SELECT OBJECT_NAME, OBJECT_TYPE 
    FROM USER_OBJECTS;

問合せの出力は次のとおりです。

OBJECT_NAME                OBJECT_TYPE
-------------------------  -------------------
EMP_DEPT                   CLUSTER
EMP                        TABLE
DEPT                       TABLE
EMP_DEPT_INDEX             INDEX
PUBLIC_EMP                 SYNONYM
EMP_MGR                    VIEW
18.11.2.2 例2: ビューとシノニムの依存性の表示

ビューまたはシノニムを作成するとき、ビューやシノニムはその基礎になるベース・オブジェクトに基づきます。ビューの依存性を明確にするには、ALL_DEPENDENCIESUSER_DEPENDENCIESおよびDBA_DEPENDENCIESデータ・ディクショナリ・ビューを使用します。

シノニムのベース・オブジェクトのリストを表示するには、ALL_SYNONYMSUSER_SYNONYMSおよびDBA_SYNONYMSデータ・ディクショナリ・ビューを使用します。たとえば、次の問合せは、ユーザーjwardによって作成されたシノニムのベース・オブジェクトをリストします。

SELECT TABLE_OWNER, TABLE_NAME, SYNONYM_NAME
    FROM DBA_SYNONYMS
    WHERE OWNER = 'JWARD';

問合せの出力は次のとおりです。

TABLE_OWNER             TABLE_NAME   SYNONYM_NAME
----------------------  -----------  -----------------
SCOTT                   DEPT         DEPT
SCOTT                   EMP          EMP