ユーザー定義型を作成します。ユーザー定義型は、オブジェクト型、コレクション型 (入れ子の表型または VARRAY 型)、または複合型とすることができます。

構文

オブジェクト型

CREATE [ OR REPLACE ] TYPE name
  [ AUTHID { DEFINER | CURRENT_USER } ]
  { IS | AS } OBJECT
( { attribute { datatype | objtype | collecttype } }
    [, ...]
  [ method_spec ] [, ...]
) [ [ NOT ] { FINAL | INSTANTIABLE } ] ...

ここで、method_spec は、次のとおりです。

  [ [ NOT ] { FINAL | INSTANTIABLE } ] ...
  [ OVERRIDING ]
    subprogram_spec

subprogram_spec は次のとおりです。

  { MEMBER | STATIC }
  { PROCEDURE proc_name
      [ ( [ SELF [ IN | IN OUT ] name ]
          [, argname [ IN | IN OUT | OUT ] argtype
                     [ DEFAULT value ]
          ] ...)
      ]
  |
    FUNCTION func_name
      [ ( [ SELF [ IN | IN OUT ] name ]
          [, argname [ IN | IN OUT | OUT ] argtype
                     [ DEFAULT value ]
          ] ...)
      ]
    RETURN rettype
  }

入れ子の表型

CREATE [ OR REPLACE ] TYPE name { IS | AS } TABLE OF
  { datatype | objtype | collecttype }

VARRAY 型

CREATE [ OR REPLACE ] TYPE name { IS | AS }
  { VARRAY | VARYING ARRAY } (maxsize) OF { datatype | objtype }

複合型

CREATE [ OR REPLACE ] TYPE name { IS | AS }
( [ attribute datatype ][, ...]
)

説明

CREATE TYPE コマンドで、ユーザー定義のデータ型を作成します。 作成できる型には、オブジェクト型、入れ子の表型、VARRAY 型、複合型があります。 入れ子の表型および VARRAY 型は、コレクション型に属します。

複合型は、Oracle データベースと互換性がありません。 ただし、複合型には SPL プログラムを使用してアクセスできます。これは、本ページで説明する他の型と同じです。

パッケージのみの場合、複合型は、パッケージ仕様またはパッケージ本体内の TYPE IS RECORD 文を使用して宣言されたユーザー定義のレコード型に含めることができます。 このような入れ子構造は、関数、ストアドプロシージャ、トリガーなど、他の SPL プログラムでは許可されていません。

CREATE TYPE コマンドでスキーマ名を指定すると、指定したスキーマに型が作成されます。 それ以外の場合、型は現在のスキーマに作成されます。 新しい型の名前は、同じスキーマ内の既存の型とは異なっている必要があります。 既存の型の定義を更新する場合は、CREATE OR REPLACE TYPE コマンドを使用できます。

  • OR REPLACE オプションを使用して、既存のオブジェクト型の属性を追加、削除、変更することはできません。 ただし、DROP TYPE コマンドを使用すれば、既存のオブジェクト型を削除できます。 OR REPLACE オプションを使用すると、既存のオブジェクト型のメソッドを追加、削除、または変更できます。
  • ALTER TYPE ALTER ATTRIBUTE コマンドの PostgreSQL フォームを使用して、既存のオブジェクト型の属性のデータ型を変更できます。 ただし、ALTER TYPE コマンドでは、オブジェクト型の属性の追加も削除もできません。

型を作成するユーザーは、型の所有者です。

パラメーター

パラメーター 説明
name 作成する型の名前。 名前はスキーマ修飾可能です。
DEFINER | CURRENT_USER オブジェクト型で参照されるデータベースオブジェクトへのアクセスを許可するかどうかを決定する特権を指定します。 DEFINER は、オブジェクト型の所有者の特権を表します。 CURRENT_USER は、オブジェクト型のメソッドを実行している現在のユーザーの特権を表しています。 デフォルト値は DEFINER です。
attribute オブジェクト型または複合型の属性の名前。
datatype オブジェクト型または複合型の属性、または作成されているコレクション型の要素を定義するデータ型。
objtype オブジェクト型の属性または作成されているコレクション型の要素を定義するオブジェクト型の名前。
collecttype オブジェクト型の属性または作成されているコレクション型の要素を定義するコレクション型の名前。
FINAL | NOT FINAL
  • オブジェクト型の場合、このパラメーターで、サブ型がオブジェクト型由来のものかどうかを指定します。 デフォルト値は FINAL で、サブ型がオブジェクト型由来のものではないことを表しています。
  • method_spec の場合、このパラメーターで、サブ型のメソッドをオーバーライドするかどうかを指定します。 デフォルト値は NOT FINAL で、サブ型でメソッドをオーバーライドできることを表しています。
INSTANTIABLE | NOT INSTANTIABLE
  • オブジェクト型の場合、このパラメーターは、このオブジェクト型のインスタンスを作成できるかどうかを指定します。 デフォルト値は INSTANTIABLE で、このオブジェクト型のインスタンスを作成できることを表しています。 NOT INSTANTIABLE を指定する場合は、NOT FINAL も指定する必要があります。 オブジェクト型のメソッドに対する method_spec に NOT INSTANTIABLE 修飾子が含まれている場合、オブジェクト型は、オブジェクト型仕様の閉じ括弧に続けて、NOT INSTANTIABLE および NOT FINAL で定義する必要があります。
  • method_spec の場合、このパラメーターは、オブジェクト型定義でメソッドを実装するかどうかを指定します。 デフォルト値は INSTANTIABLE で、オブジェクト型に対する CREATE TYPE BODY コマンドでメソッドを実装することを表しています。 NOT INSTANTIABLE を指定した場合、オブジェクト型に対する CREATE TYPE BODY コマンドでメソッドの実装を含めることはできません。
OVERRIDING OVERRIDING を指定した場合、method_spec は、同じ名前のメソッドを、同じ数の同じ名前のメソッド引数でオーバーライドします。 引数には、スーパータイプで定義されているものと同じデータ型、同じ順序、および同じ戻り値の型 (メソッドが関数の場合) があります。
MEMBER | STATIC サブプログラムがオブジェクトインスタンスで実行される場合は、MEMBER を指定します。 サブプログラムが特定のオブジェクトインスタンスとは関係なく実行される場合は、STATIC を指定します。
proc_name 作成するストアドプロシージャの名前。
SELF [ IN | IN OUT ] name メンバーメソッドの場合、SELF という名前の暗黙のビルトインパラメーターを使用できます。 このパラメーターのデータ型は、作成されるオブジェクト型のデータ型です。 SELF で、メソッドを呼び出しているオブジェクトインスタンスを参照します。 SELF は、パラメーター一覧で IN または IN OUT パラメーターとして明示的に宣言できます。 明示的に宣言する場合、パラメーター一覧で SELF を最初のパラメーターとする必要があります。 SELF を明示的に宣言しない場合、そのパラメーターモードは、メンバーストアドプロシージャに対する IN OUT およびメンバー関数に対する IN のデフォルトになります。
argname 引数の名前。 引数は、メソッド本体でこの名前で参照されます。
argtype メソッド引数のデータ型。 引数の型は、基本データ型、または入れ子の表型やオブジェクト型などのユーザー定義型にすることができます。 基本データ型の長さは指定できません。 たとえば、VARCHAR2 は指定できますが、VARCHAR2(10) は指定できません。
DEFAULT value メソッド呼び出しでデフォルト値を指定しない場合、このパラメーターで入力引数のデフォルト値を指定します。 IN OUT または OUT モードを使用して、引数に DEFAULT を指定することはできません。
func_name 作成する関数の名前。
rettype 戻り値のデータ型。これは、argtype パラメーターにリストされている型のいずれかになり得ます。 argtype については、rettype の長さを指定できません。
maxsize VARRAY の要素の最大数。

  • オブジェクト型の作成

    addr_obj_typ という名前のオブジェクト型を作成します。

    CREATE OR REPLACE TYPE addr_obj_typ AS OBJECT (
        street          VARCHAR2(30),
        city            VARCHAR2(20),
        state           CHAR(2),
        zip             NUMBER(5)
    );

    メンバーメソッド display_emp を含む emp_obj_typ という名前のオブジェクト型を作成します。

    CREATE OR REPLACE TYPE emp_obj_typ AS OBJECT (
        empno           NUMBER(4),
        ename           VARCHAR2(20),
        addr            ADDR_OBJ_TYP,
        MEMBER PROCEDURE display_emp (SELF IN OUT emp_obj_typ)
    );

    静的メソッド get_dname を含む dept_obj_typ という名前のオブジェクト型を作成します。

    CREATE OR REPLACE TYPE dept_obj_typ AS OBJECT (
        deptno          NUMBER(2),
        STATIC FUNCTION get_dname (p_deptno IN NUMBER) RETURN VARCHAR2,
        MEMBER PROCEDURE display_dept
    );
  • コレクション型の作成

    データ型 NUMBER(8,2) の budget_tbl_typ という名前の入れ子の表型を作成します。

    CREATE OR REPLACE TYPE budget_tbl_typ IS TABLE OF NUMBER(8,2);
  • 複合型の作成および使用

    次の例は、無記名ブロックから複合型にアクセスする方法を示しています。

    複合型は次のように作成されます。

    CREATE OR REPLACE TYPE emphist_typ AS (
        empno           NUMBER(4),
        ename           VARCHAR2(10),
        hiredate        DATE,
        job             VARCHAR2(9),
        sal             NUMBER(7,2)
    );

    次の例は、複合型にアクセスする無記名ブロックを示しています。

    DECLARE
        v_emphist       EMPHIST_TYP;
    BEGIN
        v_emphist.empno    := 9001;
        v_emphist.ename    := 'SMITH';
        v_emphist.hiredate := '01-AUG-17';
        v_emphist.job      := 'SALESMAN';
        v_emphist.sal      := 8000.00;
        DBMS_OUTPUT.PUT_LINE('   EMPNO: ' || v_emphist.empno);
        DBMS_OUTPUT.PUT_LINE('   ENAME: ' || v_emphist.ename);
        DBMS_OUTPUT.PUT_LINE('HIREDATE: ' || v_emphist.hiredate);
        DBMS_OUTPUT.PUT_LINE('     JOB: ' || v_emphist.job);
        DBMS_OUTPUT.PUT_LINE('     SAL: ' || v_emphist.sal);
    END;
    
       EMPNO: 9001
       ENAME: SMITH
    HIREDATE: 01-AUG-17 00:00:00
         JOB: SALESMAN
         SAL: 8000.00

    次の例は、パッケージ本体で宣言されているユーザー定義のレコード型から複合型にアクセスする方法を示しています。

    複合型は次のように作成されます。

    CREATE OR REPLACE TYPE salhist_typ AS (
        startdate       DATE,
        job             VARCHAR2(9),
        sal             NUMBER(7,2)
    );

    パッケージ仕様は次のように定義されます。

    CREATE OR REPLACE PACKAGE emp_salhist
    IS
        PROCEDURE fetch_emp (
            p_empno     IN NUMBER
        );
    END;

    パッケージ本体は次のように定義されます。

    CREATE OR REPLACE PACKAGE BODY emp_salhist
    IS
        TYPE emprec_typ IS RECORD (
            empno       NUMBER(4),
            ename       VARCHAR(10),
            salhist     SALHIST_TYP
        );
        TYPE emp_arr_typ IS TABLE OF emprec_typ INDEX BY BINARY_INTEGER;
        emp_arr         emp_arr_typ;
    
        PROCEDURE fetch_emp (
            p_empno     IN NUMBER
        )
        IS
            CURSOR emp_cur IS SELECT e.empno, e.ename, h.startdate, h.job, h.sal
                FROM emp e, jobhist h
                WHERE e.empno = p_empno
                  AND e.empno = h.empno;
    
            i           INTEGER := 0;
        BEGIN
            DBMS_OUTPUT.PUT_LINE('EMPNO  ENAME    STARTDATE  JOB         ' ||
            'SAL        ');
            DBMS_OUTPUT.PUT_LINE('-----  -------  ---------  ---------   ' ||
            '---------');
    
            FOR r_emp IN emp_cur LOOP
                i := i + 1;
                emp_arr(i) := (r_emp.empno, r_emp.ename,
                    (r_emp.startdate, r_emp.job, r_emp.sal));
            END LOOP;
    
            FOR i IN 1 .. emp_arr.COUNT LOOP
                DBMS_OUTPUT.PUT_LINE(emp_arr(i).empno || '   ' ||
                    RPAD(emp_arr(i).ename,8) || ' ' ||
                    TO_CHAR(emp_arr(i).salhist.startdate,'DD-MON-YY') || '  ' ||
                    RPAD(emp_arr(i).salhist.job,10) || ' ' ||
                    TO_CHAR(emp_arr(i).salhist.sal,'99,999.99'));
            END LOOP;
        END;
    END;

    パッケージ本体の TYPE emprec_typ IS RECORD データ構造の宣言では、salhist フィールドは、CREATE TYPE salhist_typ 文で作成された SALHIST_TYP 複合型のものであることにご注意ください。

    連想配列定義 TYPE emp_arr_typ IS TABLE OF emprec_typ により、レコード型データ構造 emprec_typ が参照されます。 データ構造には、SALHIST_TYP 複合型の salhist フィールドが含まれます。

    次の例は、emp テーブルと jobhist テーブルの結合から配列を読み込み、配列の内容を表示するパッケージストアドプロシージャを呼び出す方法を示しています。

    EXEC emp_salhist.fetch_emp(7788);
    
    EMPNO  ENAME    STARTDATE  JOB         SAL
    -----  -------  ---------  ---------   ---------
    7788   SCOTT    19-APR-87  CLERK        1,000.00
    7788   SCOTT    13-APR-88  CLERK        1,040.00
    7788   SCOTT    05-MAY-90  ANALYST      3,000.00
    
    EDB-SPL Procedure successfully completed