8.3 型進化

型進化は、オブジェクト型を変更するプロセスです。

内容は次のとおりです。

8.3.1 型進化について

次の変更を行うとオブジェクト型を進化させることができます。

  • 属性の追加および削除

  • メソッドの追加および削除

  • 長さ、精度または位取りを引き上げるための数値属性の修正

  • 文字長を長くするための可変長文字属性の修正

  • 型のFINALおよびINSTANTIABLEプロパティの変更

  • VARRAYの制限およびサイズの変更

  • コレクション要素の長さ、精度およびスケールの変更

型を変更すると、その型を参照する項目にも影響します。たとえば、新しい属性を型に追加する場合、その新しい属性を追加できるように、その型の列にあるデータを提示する必要があります。

8.3.2 型進化および依存スキーマ・オブジェクト

型の依存スキーマ・オブジェクトは、型を直接的または間接的に参照し、その型に加えられた変更に影響されるオブジェクトです。

型は、次の依存スキーマ・オブジェクトを持つことができます。表、型またはサブタイプ、プロシージャ、ファンクション、パッケージ、トリガーなどのプログラム・ユニット(PL/SQLブロック)、索引タイプ、ビュー(オブジェクト・ビューを含む)、ファンクション索引、演算子。

依存スキーマ・オブジェクトが型の変更によってどのような影響を受けるかは、オブジェクトによって、また、変更の性質によって異なります。

  • 依存プログラム・ユニット、ビュー、演算子および索引タイプは、型が変更されると、無効としてマークされます。これらの無効となったスキーマ・オブジェクトのいずれかが次回参照されると、新しい型の定義を使用して再検証されます。オブジェクトの再コンパイルが成功すると、そのオブジェクトは有効となり、再度使用できるようになります。

  • 型の変更によっては、依存ファンクション索引が削除または無効化され、再構築が必要です。

  • 依存表には、属性の型に応じて型に加えられた各属性に対して表に1つ以上の内部列が追加されます。新しい属性が追加される際は、NULL値が設定されます。削除された各属性に対応付けられている列は削除されます。変更された各属性に対応付けられた長さ、精度またはスケールも、変更内容に対応して変更されます。

これらの変更は、主に表のメタデータの更新を含み、迅速に実行できます。ただし、このような表のデータは、「データを更新するオプション」で説明するように、型の新しいバージョンの形式にあわせて更新する必要があります。

8.3.3 データを更新するオプション

更新は、データの量によっては時間がかかる場合があるため、ALTER TYPEコマンドにオプションが用意されています。このオプションによって、すべての依存表データを即時変換するか、元の形式のままにしておいて、更新のたびに少しずつ変換するかを選択できます。

ALTER TYPECASCADEオプションは、型の変更を依存型および依存表に伝播します。CASCADE自体に、伝播の一環として表データを新しい型形式に変換するかどうかを選択できる次のオプションがあります。

  • INCLUDING TABLE DATA: データを変換します(デフォルト)

  • NOT INCLUDING TABLE DATA : データを変換しません

デフォルトでは、CASCADEオプションはデータを変換します。いずれの場合も、表データは常に最新バージョンの型の形式で戻されます。表データが以前の型バージョンの形式で保存されている場合は、データが実際に保存されている形式はデータが再書込みされないかぎり変更されないにしても、そのデータは、戻される前に最新バージョンの形式に変換されます。

最新の型の定義は、システム・ビューUSER_SOURCEから取り出せます。USER_TYPE_VERSIONSビューで、ある型のすべてのバージョンの定義を参照できます。

関連項目:

8.3.4 型への構造的な変更の影響

型に対する構造的な変更が依存データに影響し、データの変換を必要とします。これは、ある型のメソッドの定義や動作(実装)に限定された変更には適用されません。

型に対する次の変更は構造的変更です。

  • 属性の追加または削除

  • 属性の長さ、精度、スケールの変更

  • FINALからNOT FINAL(またはその逆)への型のファイナリティの変更

このような変更の結果、変更された型およびそのすべての依存型のバージョンが新しいバージョンになり、新しいバージョンへの変更のプロセスの一環として、依存表の内部列が追加、削除または変更されます。

これらのいずれかの変更を、依存型または依存表を持つ型に対して実行すると、変更を伝播した影響は、メタデータのみでなく、データ記憶域の構成にも影響し、データの変換を必要とします。

データの変換以外にも、変更すべき項目がある場合があります。たとえば、新しい属性が型に追加されて、その型が、その型のコンストラクタをコールする場合、型本体の各コンストラクタは、新しい属性に対する値を指定するように修正する必要があります。同様に、新しいメソッドが追加される場合は、型本体を置換して、新しいメソッドの実装を追加する必要があります。型本体は、CREATE OR REPLACE TYPE BODY文を使用して変更できます。

8.3.5 属性の追加および削除による型の変更

ある属性を追加して別の属性を削除することにより、型に単純な変更を加えることができます。

例8-5では、person_typeに対してこのような変更を加えています。CASCADEキーワードは、型の変更を依存型および依存表に伝播しますが、NOT INCLUDING TABLE DATA句によって関連するデータの変換が阻止されています。

例8-5 属性の追加および削除によるオブジェクト型の変更

-- Drop person_typ and person_obj_table if they exist
CREATE TYPE person_typ AS OBJECT (
  idno           NUMBER,
  name           VARCHAR2(30),
  phone          VARCHAR2(20));
/
CREATE TABLE person_obj_table OF person_typ;

INSERT INTO person_obj_table 
  VALUES (person_typ(12, 'Bob Jones', '650-555-0130'));

SELECT value(p) FROM person_obj_table p;
VALUE(P)(IDNO, NAME, PHONE)
--------------------------------------------
PERSON_TYP(12, 'Bob Jones', '650-555-0130')

次のように電子メール属性を追加し、電話属性を削除できます。

ALTER TYPE person_typ
  ADD ATTRIBUTE (email VARCHAR2(80)), 
  DROP ATTRIBUTE phone CASCADE NOT INCLUDING TABLE DATA;

次に、型の変更に対応するために切断して再接続することができます。

connect oe/oe;
connect hr/hr;
ALTER SESSION SET PLSQL_WARNINGS = 'enable:all';
-- The data of table person_obj_table has not been converted yet, but
-- when the data is retrieved, Oracle returns the data based on
-- the latest type version. The new attribute is initialized to NULL.
SELECT value(p) FROM person_obj_table p;
VALUE(P)(IDNO, NAME, EMAIL)
---------------------------------
PERSON_TYP(12, 'Bob Jones', NULL)

SELECT文では、列データが最新の型バージョンに変換されている可能性があるとしても、変換されたデータが列に再度書き込まれることはありません。ある表の特定のユーザー定義型の列が頻繁に取り出される場合、データ変換が重複して行われないようにするため、そのデータを最新の型バージョンに変換することを検討してください。変換は、列にオブジェクトやネストした表列より変換に必要な時間が通常長くなるVARRAY属性が含まれている場合、特に大きな効果があります。

前のコードと関連していない次のコード・スニペットに示すように、UPDATE文を発行して列をそれ自体に設定し、データの列を変換できます。

UPDATE dept_tab SET emp_array_col = emp_array_col;

ある表内のすべての列を、UPGRADE INCLUDING DATAとともにALTER TABLEを使用して変換できます。次に例を示します。

ALTER TYPE person_typ ADD ATTRIBUTE (photo BLOB)
  CASCADE NOT INCLUDING TABLE DATA;
ALTER TABLE person_obj_table UPGRADE INCLUDING DATA;

ALTER TABLE行は、リストされた表のみを変換します。CASCADEオプションは、他の表または依存オブジェクトが変換されないようにします。

8.3.6 ネストした表属性の追加による型の変更

ネストした表に含まれているオブジェクト型に、ネストした表属性を追加できます。

この複雑な変更を型に加えるには、次の手順を実行する必要があります。

この手順では、手順1のコードで変更される次の初期スキーマが必要です。

初期スキーマ

-- Drop existing person_typ, department_type, people_typ objects or tables
CREATE TYPE person_typ AS OBJECT (
  idno           NUMBER,
  name           VARCHAR2(30),
  phone          VARCHAR2(20));
/
-- creating a nested table type
CREATE TYPE people_typ AS TABLE OF person_typ;/
CREATE TYPE department_typ AS OBJECT (
  manager    person_typ,
  employee   people_typ);  // a nested table/
CREATE TABLE department OF department_typ
  NESTED TABLE employee STORE AS employee_store_nt;

手順1のコード例は、新しいオブジェクトtasks_typおよびそれを保持するネストした表の型tasks_nttabの作成から開始されます。

手順1のコード例と他のプログラムの両方で、属性としてネストした表tasksをネストした表people_typにすでに含まれているオブジェクト型person_typに追加するために、次の手順が必要です。

  1. .

    ネストした表属性の追加によるオブジェクト型の変更

    -- Requires Ex. 8-6
    CREATE TYPE tasks_typ AS OBJECT (
      priority       VARCHAR2(2),
      description    VARCHAR2(30));
    /
    
    CREATE TYPE tasks_nttab AS TABLE OF tasks_typ;
    /
    
    -- Propagate the change to employee_store_nt
    -- Specify a storage name for the new nested table
    ALTER TABLE employee_store_nt
      UPGRADE NESTED TABLE tasks STORE AS tasks_nt;
    
  2. 必要な場合はperson_typに対するCREATE OR REPLACE TYPE BODYを使用して、対応する型本体を更新して、新しい型定義に更新します。
  3. 依存表を最新の型バージョンにアップグレードし、表データを変換します。これにより、表が検証され、データ・アクセスが再度許可されます。
    ALTER TABLE department UPGRADE INCLUDING DATA;
    
  4. 必要に応じて、PL/SQL依存プログラム・ユニットを変更して、型に加えられた変更に対応します。
  5. アプリケーションがC言語で書かれているか、Javaで書かれているかによって、OTTまたはJPublisherを使用して、新しいヘッダー・ファイルを生成します。

    スーパータイプに新しい属性を追加すると、そのすべてのサブタイプが新しい属性を継承するため、サブタイプの属性数も増えます。継承された属性は、常に、宣言された(ローカルに定義された)属性に優先するので、新しい属性をスーパータイプに追加すると、サブタイプのすべての宣言された属性の順序が1つずつ再帰的に増えます。

    変更された型のマッピングを更新して、新しい属性を追加する必要があります。これは、Oracle Type Translator (OTT)およびJPublisherによって行われます。別のツールを使用する場合は、型のヘッダーがサーバーでの型の定義と適切に同期されていることを確認する必要があります。この同期が確実に行われない場合は、予期しない動作が発生する可能性があります。

  6. 必要に応じてアプリケーション・コードを修正し、アプリケーションを再作成します。

8.3.7 変更された型の妥当性チェックについて

ALTER TYPE文の実行の際に、最初に、要求された型の変更について、構文上およびセマンティクス上の妥当性がチェックされます。

CREATE TYPE文についても同様の妥当性チェックおよび追加の妥当性チェックが実行されます。ターゲットの型の新しい指定またはその依存型のいずれかについて型の妥当性が確認されない場合は、ALTER TYPE文は異常終了します。この場合は、新しい型バージョンは作成されず、すべての依存オブジェクトが変更されないままになります。

依存表が存在する場合は、さらにチェックが行われて、表および索引に関連する制約が遵守されているかが確認されます。たとえば、削除の対象となっている属性が、パーティション化キーで使用されていないかが確認されます。ここでも、ALTER TYPE文について、表に関連する制約のチェックが失敗すると、型の変更は異常終了し、その型の新しいバージョンは作成されません。

単一のALTER TYPE文で複数の属性を追加する場合、指定された順序で実行されます。1つのALTER TYPE文で複数の型の変更を指定することはできますが、属性名およびメソッド・シグネチャは1回のみの指定となります。たとえば、単一の文で同じ属性の追加と変更を行うことはできません。

次の項では、次の型の変更に関するその他の注意事項について説明します。

属性の削除

  • ルート型から属性をすべて削除することはできません。かわりに、型を削除する必要があります。サブタイプのすべての属性はスーパータイプから継承されるため、サブタイプからすべての属性を削除しても、その属性のカウントは0 (ゼロ)にはなりません。したがって、サブタイプでローカルに宣言された属性を削除することは可能です。

  • ターゲットの型でローカルに宣言された型のみを削除できます。継承された属性を、サブタイプから削除することはできません。属性がローカルに宣言された場所でその型からその属性を削除してください。

  • 表パーティションの一部である属性または表のサブパーティション・キーの削除はできません。

  • 属性が削除されると、削除された属性に対応する列は削除されます。

  • 属性を削除すると、索引、統計、制約、および属性を参照する参照整合性制約が削除されます。

属性の型の長さ、精度、スケールの変更

  • 依存表のファンクション索引、クラスタ・キーまたはドメイン索引で参照される属性の長さは拡張できません。

  • 属性の長さ、精度、スケールを縮小できません。

メソッドの削除

  • メソッドは、そのメソッドの定義(または再定義)が行われた型からのみ削除できます。継承されたメソッドをサブタイプから削除することはできません。また、再定義したメソッドをスーパータイプから削除することもできません。

  • メソッドが再定義されていない場合、CASCADEオプションを使用してそのメソッドを削除すると、ターゲットの型に由来するメソッドおよびすべてのサブタイプが削除されます。一方、メソッドがサブタイプで再定義されている場合は、CASCADEは実行されないで、ロールバックされます。CASCADEが実行されるためには、メソッドを定義しているサブタイプから再定義されたメソッドを削除して、その後、スーパータイプからメソッドを削除します。

    USER_DEPENDENCIES表に、型も含めて、与えられた型に依存するすべてのスキーマ・オブジェクトがあります。また、DBMS_UTILITY.GET_DEPENDENCYユーティリティを実行して、型の依存関係を検索できます。

  • INVALIDATEオプションを使用して、再定義されたメソッドを削除できますが、サブタイプの再定義されたバージョンは、依然として手動で削除する必要があります。サブタイプは、再定義されたバージョンを削除するように明示的に変更されないかぎり、無効な状態のままです。それまでは、妥当性チェックのためにサブタイプを再コンパイルしようとすると、「メソッドは上書きしません。」というエラーが発生します。

    CASCADEとは異なり、INVALIDATEは、型および表のすべてのチェックを回避して、その型に依存するすべてのスキーマ・オブジェクトを無効とします。それらのオブジェクトは、次回のアクセス時に再検証されます。このオプションは、CASCADEを使用するより高速に処理されますが、依存型および依存表の再検証時に問題が発生しないことが確認されている必要があります。表が無効な場合は、表データにはアクセスできません。表の妥当性が検証できない場合は、そのデータはアクセス不可のままとなります。

INSTANTIABLEプロパティの変更

  • その型に表依存オブジェクトがない場合にかぎり、オブジェクト型をINSTANTIABLEからNOT INSTANTIABLEへ変更できます。

  • オブジェクト型のNOT INSTANTIABLEからINSTANTIABLEへの変更は任意の時点で実行できます。このように変更した場合、表には影響しません。

FINALプロパティの変更

  • ターゲットの型にサブタイプがない場合にかぎり、オブジェクト型をNOT FINALからFINALへ変更できます。

  • オブジェクト型をFINALからNOT FINAL、またはその逆に変更する場合は、CASCADEを使用して依存列内および依存表内のデータを即時変換する必要があります。CASCADEオプションNOT INCLUDING TABLE DATAを使用して、データを遅延させることはできません。

    • NOT FINALからFINALへは、CASCADE INCLUDING TABLE DATAを使用する必要があります。

    • FINALからNOT FINALへは、CASCADE INCLUDING TABLE DATAまたはCASCADE CONVERT TO SUBSTITUTABLEのいずれかを使用できます。

      FINALからNOT FINALに型を変更する場合、変更した型の新しいサブタイプを既存の列および表に挿入するかどうかに基づいて、CASCADEオプションを選択します。

    デフォルトでは、型をFINALからNOT FINALに変更することで、代入可能な新しい表およびその型の列を作成できますが、その型の既存の列(またはオブジェクト表)が自動的に代入可能になることはありません。実際、その逆の動作となります。その型の既存の列および表はNOT SUBSTITUTABLE AT ALL LEVELSとマークされます。これらの列の埋込み属性が代入可能な場合は、エラーが生成されます。変更された型の新しいサブタイプは、これらの既存の列および表には挿入できません。

    型の既存の列および表を代入可能にするようオブジェクト型をNOT FINALに変更する場合(NOT SUBSTITUTABLEとマークされていないことを前提)は、CASCADEオプションCONVERT TO SUBSTITUTABLEを使用します。

    次の例に、オプションCONVERT TO SUBSTITUTABLEを指定したCASCADEの使用を示します。

    CREATE TYPE shape AS OBJECT (
        name VARCHAR2(30),
        area NUMBER)
        FINAL;/
    ALTER TYPE shape NOT FINAL CASCADE CONVERT TO SUBSTITUTABLE;

    このCASCADEオプションにより既存の列がSUBSTITUTABLE AT ALL LEVELSとマークされ、列に格納されたインスタンスの型ID用に新しい非表示列が追加されます。その後、変更された型のサブタイプ・インスタンスを列に格納できます。

8.3.8 型進化に使用するALTER TYPE文

表8-1に、型の属性またはメソッド定義を変更するために使用するALTER TYPEおよびALTER TYPE...CASCADE文の一部の重要なオプションを示します。

表8-1 型進化に使用するALTER TYPEオプション

オプション 説明

CASCADE

型の変更を依存する型および表に伝播します。この文は、FORCEオプションが指定されていないかぎり、依存型または依存表にエラーが検出されると異常終了します。

他のオプションなしにCASCADEが指定されていると、CASCADEに対してINCLUDING TABLE DATAオプションが暗黙的に指定され、すべての表データが最新の型バージョンに変換されます。

INCLUDING TABLE DATA (CASCADEのオプション)

すべてのユーザー定義列に格納されているデータを、列の型の最新バージョンに変換します。

列の型に追加された新しい各属性の場合は、新しい属性がデータに追加され、NULLに初期化されます。参照される型から削除される各属性の場合は、対応する属性データが表から削除されます。表のデータが格納されているすべての表領域は、読取り/書込みモードである必要があります。読取り/書込みモードではない場合、この文は失敗します。

NOT INCLUDING TABLE DATA (CASCADEのオプション)

列データをそのまま維持し、型バージョンを変更しません。属性が表が参照する型から削除されても、削除された属性の対応する列は表から削除されません。ただし、その列のメタデータが未使用とマークされるのみです。削除された属性が列外(たとえば、VARRAY属性、LOB属性、またはネストした表属性)に格納されている場合は、その列外のデータは削除されません。(使用されない列は、後で、ALTER TABLE DROP UNUSED COLUMNS文を使用して削除できます。)

このオプションは、数多くの大きな表があり、1つのトランザクションでそのすべてを変換すると、ロールバック・セグメントが不足する可能性がある場合に使用します。このオプションを使用して、後で、各依存表のデータを、別個のトランザクションで変換できます(ALTER TABLE UPGRADE INCLUDING DATA文を使用します)。

このオプションを指定すると、表のデータは、以前の型バージョンの形式のまま維持されるので、表の更新が高速化されます。ただし、この表からデータを選択するには、その列に格納されているイメージを最新の型バージョンに変換する必要があります。この操作は、後続のSELECT文が実行される際のパフォーマンスに影響を及ぼす可能性があります。

このオプションは、表のメタデータの更新のみを必要とするため、文を正常に実行するためにすべての表領域の読取り/書込みモードでのオンライン化が必要なわけではありません。

FORCE (CASCADEのオプション)

システムに、依存表および索引からのエラーを無視させます。エラーについては、後で問合せができるように、指定された例外表にログが作成されます。一部の表でエラーが発生した場合、依存表にアクセスできなくなる可能性があるので、このオプションは慎重に使用してください。

CONVERT TO SUBSTITUTABLE (CASCADEのオプション)

型をFINALからNOT FINALに変更する場合に使用するオプションです。すべてのユーザー定義列に格納されているデータを、最新バージョンの列の型に変換し、型の新しく作成されたサブタイプがSUBSTITUTABLE AT ALL LEVELS型の既存の列およびオブジェクト表に格納できるように、これらの列および表をマークします。

このオプションを指定せずに、型をNOT FINALに変更した場合、その型の既存の列および表はNOT SUBSTITUTABLE AT ALL LEVELSとマークされ、その型の新しいサブタイプをこれらの列および表に格納できません。型が変更された後に作成される列および表にのみこれらのサブタイプを格納できます。

関連項目:

ALTER TYPEオプションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください

8.3.9 型進化に使用するALTER TABLE文

ALTER TABLEを使用して、参照される型の最新バージョンに表データを変換できます。例は、「ネストした表属性の追加による型の変更」を参照してください。

関連項目: