10 データベースへのアプリケーション・データ使用状況の登録

この章では、アプリケーション・データ使用状況のドメインおよび注釈と呼ばれる集中管理型のデータベース中心エンティティを使用して、アプリケーション・データの用途に関する情報を登録する方法について説明します。

Oracle Database 23cでは、データの用途情報を処理するためにアプリケーション使用状況ドメインと注釈を使用する、集中管理型のデータベース中心アプローチが導入されています。使用状況ドメインと注釈を一元的にデータベースに追加して、データの用途が登録されていると、様々なアプリケーションとツールからアクセスできるようになります。

関連項目:

10.1 アプリケーション使用状況ドメイン

この項では、アプリケーションでアプリケーション使用状況ドメイン(以下、「使用状況ドメイン」)を使用する方法について説明します。

10.1.1 使用状況ドメインの概要

使用状況ドメインは、軽量な使用状況指定子で、オプションでデータベース側に適用されます。この指定子は、アプリケーションが対象データの使用状況を一元的に文書化するために使用できます。高レベルのディクショナリ・オブジェクトとして、使用状況ドメインには、表列に関連付けられた組込みの使用状況プロパティ(デフォルト値、チェック制約、照合、表示書式や順序書式、注釈など)が含まれています。一元化したドメイン情報により、アプリケーションはアプリケーションレベルのメタデータに依存することなく操作を標準化できます。たとえば、使用状況ドメインは、クレジット・カード番号のマスクや、電話番号と通貨値の書式設定に使用できます。

データベース・オブジェクトとして、使用状況ドメインはスキーマに属し、基礎となる列データ型を変更することなく共通の列定義を提供します。使用状況ドメインは、表列のいくつかの共通する特性を再利用可能なオブジェクトにカプセル化します。このオブジェクトは、そうした特性を繰り返すことなく別の表列で再利用できます。

たとえば、スキーマには請求Eメール、伝票Eメール、顧客担当者EメールなどのEメール・アドレスを保持する列がある多数の表が含まれていることがあります。電子メール・アドレスは、"@"記号を必要とする特別な形式を持ちます。電子メール・アドレス用の使用状況ドメインは、regexp_like (email_dom, '^(\S+)\@(\S+)\.(\S+)$')などのチェック制約を使用して定義できます。このドメインを別の電子メールの列に関連付けることで、アプリケーションは関連付けられた列の電子メール・アドレスをドメイン名の前に"@"記号が付いた標準形式で表示できます。同様に、自動車のライセンス・プレートの表示形式を標準化することもできます。この形式には、番号とその他の情報を分離するハイフンが必要になることがあります。使用状況ドメインを使用すると、このライセンス情報は、ライセンス列のデータ型がvarchar2(6)の場合でも"ABC-123"の形式で表示できます。

使用状況ドメインを使用する利点は、アプリケーション全体で一貫した値の処理ができることと、アプリケーション全体で列のプロパティと制約を再利用できるためにコーディングが削減されることです。また、アプリケーションが操作対象データを理解するために該当する使用状況ドメインについて問い合せることができることから操作の一貫性と明確さを確保できます。

関連項目:

アプリケーション使用状況ドメインの詳細は、『Oracle Database概要』を参照してください

10.1.2 使用状況ドメインのタイプと使用する局面

ドメインのタイプには、単一列ドメイン、複数列ドメインおよびフレキシブル・ドメインの3種類があります。

単一列使用状況ドメイン

単一列使用状況ドメインは1つの列に対して作成され、アプリケーション全体で列の使用状況定義を一貫させる場合に使用します。たとえば、単一列ドメインは電子メール・アドレス用、郵便番号用、または車両番号用に作成できます。

複数列またはフレキシブルという接頭辞が付いていない場合、このドキュメントでは、「使用状況ドメイン」または「ドメイン」は単一列使用状況ドメインを意味します。

複数列使用状況ドメイン

複数列使用状況ドメインでは、1つのドメインで複数の列の列使用状況定義を作成します。複数列使用状況ドメインは、複数の表列にまたがる論理エンティティがある場合に理想的です。たとえば、複数列使用状況ドメインは、住所を表すために使用できます。

フレキシブル使用状況ドメイン

フレキシブル使用状況ドメインは、判別式列の値に基づいて単一列または複数列の使用状況ドメインのセットから動的に選択するドメインです。フレキシブル・ドメインは、1つ以上の判別式列で構成されるマッピング式に基づいて、特定のドメイン(構成要素ドメインとも呼ばれる)を値列のセットに割り当てます。

これらの使用状況ドメインのタイプに加えて、表列に対する組込みの使用状況ドメインを直接使用することもできます。例として、email_d、ssn_dおよびcredit_card_number_dが挙げられます。

関連項目:

10.1.3 使用状況ドメインに必要な権限

使用状況ドメインを操作するには、次の権限が必要です。

ノート:

データベース管理者(DBA)ロールには、次のすべての権限が含まれています。

DDL権限 アクション

CREATE DOMAIN

自分のスキーマ内にドメインを作成できます。

RESOURCEロールとDB_DEVELOPER_ROLEロールには、CREATE DOMAIN権限が含まれています。

CREATE ANY DOMAIN

任意のスキーマ内にドメインを作成できます。

ALTER ANY DOMAIN

任意のスキーマ内のドメインを変更できます。

DROP ANY DOMAIN

任意のスキーマ内のドメインを削除できます。

EXECUTE ANY DOMAIN

任意のスキーマ内のドメインを使用および参照できます。

ユーザーに任意のスキーマ内のドメイン対する実行権限を明示的に付与するには、次のコードを使用します。

GRANT EXECUTE ON <schemaName.domainName> TO <user>;

10.1.4 単一列使用状況ドメインの使用

この項では、単一列使用状況ドメイン(これ以降、「使用状況ドメイン」または「ドメイン」と表記)を作成、関連付け、変更、関連付け解除および削除する方法について説明します。

10.1.4.1 使用状況ドメインの作成

電子メール・アドレスやクレジット・カード番号など、共通の値を表すオプションのプロパティと制約のセットをカプセル化するために、使用状況ドメインを定義できます。

次に、いくつかの使用状況ドメインの作成例を示します。この例のドメインは、表列のプロパティ(デフォルト値、制約、注釈、表示と順序の式など)に基づいています。

例10-1 時給用の使用状況ドメインの作成

人材管理アプリケーション(HRA)では、それぞれの会社ごとに多数の表を作成します。ほとんどの会社には、時給を格納する列があります。HRAでは、次のようにして時給列用の使用状況ドメインを作成できます。

CREATE DOMAIN HourlyWages AS NUMBER
  DEFAULT ON NULL 15
  CONSTRAINT MinimalWage CHECK (HourlyWages > = 7 AND HourlyWages <=1000) ENABLE
  DISPLAY TO_CHAR(HourlyWages, '$999.99')  ORDER ( -1*HourlyWages )
  ANNOTATIONS (properties '{"Purpose": "Wages", "Applicability": "USA", "Industry": {"Sales", "Manufacturing"} }');

例10-2 サロゲート・キー用の使用状況ドメインの作成

データベース・アプリケーションでサロゲート・キー列に注釈を付けて、該当する列の標準メタデータを維持する場合は、次のようなドメインを作成します。

CREATE DOMAIN surrogate_id AS INTEGER
  STRICT
  NOT NULL
  ANNOTATIONS ( primary_key, mandatory, operations '["insert", "delete"]' );

例10-3 生年月日用の使用状況ドメインの作成

次の使用状況ドメインでは、生年月日のすべての列が"日付のみ"であることを確実にして、年齢が年数で表示されるようにします。

CREATE DOMAIN birth_date AS DATE
  CONSTRAINT birth_date_only_c check ( birth_date = trunc ( birth_date ) )
  DISPLAY FLOOR ( months_between ( sysdate, birth_date ) / 12 ) || ' years'
  ANNOTATIONS ( sensitive 'PII Data', operations '["insert", "update"]' );

例10-4 デフォルトの日時値用の使用状況ドメインの作成

日時値用の使用状況ドメインを作成することで、挿入が標準形式であることを確実にします。

CREATE DOMAIN insert_timestamp AS
  TIMESTAMP WITH LOCAL TIME ZONE
  DEFAULT ON NULL systimestamp;

例10-5 正の身長用の使用状況ドメインの作成

次の使用状況ドメインでは、個人の身長が正であることを確実にして、身長が降順にソートされます。

CREATE DOMAIN height AS NUMBER
  CONSTRAINT positive_height_c CHECK ( value > 0 )
  ORDER value * -1
  ANNOTATIONS ( operations '["insert", "update"]' );

例10-6 正の体重用の使用状況ドメインの作成

次の使用状況ドメインでは、個人の体重が正であることを確実にします。

CREATE DOMAIN weight AS NUMBER
  CONSTRAINT positive_weight_c CHECK ( value > 0 )
  ANNOTATIONS ( operations '["insert", "update"]' );

例10-7 チェック制約が複数あるドメインの定義

次の例のように、複数のCHECK制約がある電子メール・アドレス用の使用状況ドメインを定義できます。

CREATE SEQUENCE IF NOT EXISTS email_seq;

CREATE DOMAIN email AS VARCHAR2(100) 
  DEFAULT ON NULL email_seq.NEXTVAL || '@domain.com' 
  CONSTRAINT email_c CHECK (REGEXP_LIKE (email, '^(\S+)\@(\S+)\.(\S+)$')) 
  CONSTRAINT email_max_len_c CHECK (LENGTH(email) <=100) DEFERRABLE INITIALLY DEFERRED
  DISPLAY '---' || SUBSTR(email, INSTR(email, '@') + 1);

両方の制約を満たすVARCHAR2(L [BYTE|CHAR])データ型の任意の列をドメインに関連付けできます。INITIALLY DEFERRED句により、制約email_max_len_cの値の検証をコミット時まで延期します。

例10-8 JSONスキーマの検証

次の例のように、再利用可能なJSONスキーマ検証にもドメインが使用できます。

CREATE DOMAIN department_json_doc AS JSON 
  CONSTRAINT CHECK ( 
    department_json_doc IS JSON VALIDATE USING '{
      "type": "object",
      "properties": {
        "departmentName": { "type": "string" },
        "employees": { "type": "array" }
      },
      "required" : [ "departmentName", "employees" ],
      "additionalProperties": false
    }' );

関連項目:

10.1.4.2 表作成時の使用状況ドメインと列の関連付け

使用状況ドメインの定義後に、そのドメインは表の作成時に新しい表列に関連付けることも、既存の表の既存の列に関連付けることもできます。使用状況ドメインを列に関連付けると、そのドメインのオプションのプロパティと制約が列に明示的に適用されます。

CREATE TABLE DDLを使用すると、新しく作成した列に使用状況ドメインを関連付けることができます。次の例は、新しい表列に使用状況ドメインを関連付ける方法を示しています。次に示す各例は、前述の例で作成した使用状況ドメインを使用しています。

例10-9 表作成時のHourlyWages使用状況ドメインの関連付け

HourlyWagesドメインを使用すると、HRAは賃金列のドメイン特性が同じになる複数の表を作成できます。

CREATE TABLE employee (
  name VARCHAR2(100),
  id NUMBER,
  wage NUMBER DOMAIN HourlyWages);
CREATE TABLE wage (
  name VARCHAR2(100),
  id NUMBER,
  wage NUMBER DOMAIN HourlyWages,
  gross_pay NUMBER,
  deductions NUMBER,
  net_pay NUMBER);

例10-10 表作成時のsurrogate_id使用状況ドメインの関連付け

列にsurrogate_idなどの厳密な使用状況ドメインを関連付ける場合は、関連付けられる列のデータ型がドメインと同じであることを確認してください。厳密なドメインでは、列の長さ、スケールおよび精度がドメインと一致することも必要です。

次のコードは、NUMBERデータ型の列をINTEGER/NUMBER(*,0)データ型のドメインにリンクしようとしているため、ORA-11517: the column data type does not match the domain columnで失敗します。

CREATE TABLE orders (
  order_id NUMBER DOMAIN surrogate_id,
  customer_id NUMBER,
  order_datetime TIMESTAMP WITH LOCAL TIME ZONE
    DEFAULT SYSTIMESTAMP);

この関連付けが機能するように、NUMBER(*,0)列データ型を使用して、surrogate_id使用状況ドメイン(INTEGER == NUMBER(*,0))に関連付けできます。

CREATE TABLE orders (
  order_id NUMBER(*,0) DOMAIN surrogate_id,
  customer_id NUMBER,
  order_datetime TIMESTAMP WITH LOCAL TIME ZONE
    DEFAULT SYSTIMESTAMP); 

例10-11 表作成時のsurrogate_idbirth_dateheightおよびweight使用状況ドメインの関連付け

DOMAINキーワードはオプションです。次の例では、DOMAINキーワードなしで、birth_dateドメインがdate_of_birth列に関連付けられていることがわかります。この例は、精度とスケールに関して、ドメイン内のものよりも正確なデータ型を定義できることも示しています。height_in_cm列とweight_in_kg列には、NUMBERとしてのドメイン・データ型が関連付けられていますが、列データ型にはNUMBER(4,1)などの精度およびスケール値があります。

CREATE TABLE people (
  person_id     DOMAIN surrogate_id
    GENERATED BY DEFAULT AS IDENTITY
    PRIMARY KEY,
  full_name     VARCHAR2(256),
  date_of_birth birth_date,
  height_in_cm  NUMBER(4, 1) DOMAIN height,
  weight_in_kg  NUMBER(6, 3) DOMAIN weight);

例10-12 表作成時のdepartment_json_doc使用状況ドメインの関連付け

CREATE TABLE departments (
  department_id  INTEGER PRIMARY KEY,
  department_doc JSON DOMAIN department_json_doc);

ガイドライン

  • ドメインを列に関連付けるときには、列のデータ型に加えてドメイン名も指定できます。この場合は、ドメインのデータ型が列のデータ型と互換性があるときには、列のデータ型が使用されます。

  • ドメインを列に関連付けるときには、列のデータ型のかわりにドメイン名を指定できます。この場合は、ドメイン・データ型が列に使用されます。そのときには、DOMAINキーワードがオプションになります。

  • ドメインがSTRICTとして定義されているときには、ドメインのデータ型、スケールおよび精度が列のデータ型、スケールおよび精度と一致する必要があります。

  • ドメインがSTRICTとして定義されていないときには、任意の長さの列に任意の長さのドメインを関連付けできます。たとえば、VARCHAR2(10)のドメインは任意のVARCHAR2列に関連付けできます。

関連項目:

  • 使用状況ドメインの作成に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: CREATE DOMAINを参照してください

  • 列とドメインのデータ型に関する詳細は、「ドメインのデータ型の指定」を参照してください

10.1.4.2.1 使用状況ドメインに関連付けられた列に対するDMLの使用

次に、使用状況ドメインが関連付けられた新しく作成する表列に使用できるDML文の例をいくつか示します。

例10-13 people表に対するDML文の使用

次のINSERTコマンドは、people表の列にデータを挿入します。そのときに、関連付けられたドメインで指定されたチェック制約に違反していないことを確認します。

INSERT INTO people
  VALUES ( 1, 'Sally Squirell', date'1981-01-01', 180.1, 61 );

INSERT INTO people
  VALUES ( 2, 'Brian Badger', date'2016-12-31', 120.4, 27.181 );
 

次のINSERTコマンドは、heightが負の数として指定されていることから、関連するチェック制約に違反するために失敗します。

INSERT INTO people
  VALUES ( 3, 'Fergal Fox', date'2023-04-12', -99, 1 );

出力は次のとおりです。

ORA-11534: check constraint (HR.SYS_C009232) due to domain constraint HR.POSITIVE_HEIGHT_C of domain HR.HEIGHT violated

関連付けられたドメインを使用することで、身長が降順でソートされたデータを表示し、それに対応する年齢と体重も表示できます。

SELECT full_name, DOMAIN_DISPLAY ( date_of_birth ) age,
       height_in_cm, weight_in_kg
  FROM people
  ORDER BY DOMAIN_ORDER ( height_in_cm );

関連項目:

DOMAIN_DISPLAYDOMAIN_ORDERなどのドメイン関数の詳細は、「ドメイン使用状況用のSQL関数」を参照してください。

出力は次のとおりです。


FULL_NAME            AGE        HEIGHT_IN_CM WEIGHT_IN_KG
-------------------- ---------- ------------ ------------
Sally Squirell       42 years          180.1           61
Brian Badger         6 years           120.4       27.181

people表は、データ型定義と参照先ドメイン情報を確認するように記述できます。

DESC people;

出力は次のとおりです。


 Name                   Null?    Type
 ---------------------- -------- ----------------------------------------
 PERSON_ID              NOT NULL NUMBER(38) HR.SURROGATE_ID
 FULL_NAME                       VARCHAR2(256)
 DATE_OF_BIRTH                   DATE HR.BIRTH_DATE
 HEIGHT_IN_CM                    NUMBER(4,1) HR.HEIGHT
 WEIGHT_IN_KG                    NUMBER(6,3) HR.WEIGHT

次のSELECTコマンドを使用すると、関連付けられたドメインから継承されている列の注釈を表示できます。


SELECT column_name, annotation_name, annotation_value 
  FROM user_annotations_usage
  WHERE object_name = 'PEOPLE';

出力は次のとおりです。


COLUMN_NAME          ANNOTATION_NAME      ANNOTATION_VALUE    
-------------------- -------------------- --------------------
PERSON_ID            PRIMARY_KEY          <null>              
PERSON_ID            MANDATORY            <null>              
PERSON_ID            OPERATIONS           ["insert", "delete"]
DATE_OF_BIRTH        OPERATIONS           ["insert", "update"]
DATE_OF_BIRTH        SENSITIVE            PII Data            
HEIGHT_IN_CM         OPERATIONS           ["insert", "update"]
WEIGHT_IN_KG         OPERATIONS           ["insert", "update"]

例10-14 JSONデータを使用したdepartments表に対するDML文の使用

次のdepartments表に対するINSERTコマンドは、department_json_docドメイン内のすべてのJSON属性が含まれているために成功します。

INSERT INTO departments 
  VALUES ( 1, '{
    "departmentName" : "Accounting", 
    "employees" : [
      {"empName":"William"},
      {"empName":"Shelley"}
    ]
  }');

次のINSERTコマンドは、employees属性がないために、ORA-40875: JSON schema validation error - missing employees attributeで失敗します。

INSERT INTO departments 
  VALUES ( 2, '{
    "departmentName" : "Finance"
  }');

次のINSERTコマンドは、関連付けられたdepartment_json_doc使用状況ドメイン内にmanager属性が見つからないために、ORA-40875: JSON schema validation error - extra manager attributeで失敗します。

INSERT INTO departments
  VALUES ( 3, '{
    "departmentName" : "Executive", 
    "employees" : [
      {"empName":"Lex"},
      {"empName":"Neena"}
    ],
    "manager" : {"empName":"Lex"}
  }');
10.1.4.3 使用状況ドメインと既存または新規の列の関連付け

ALTER TABLE DDLは、MODIFY句またはADD句とともに使用することで、既存の列または新規に追加された列に使用状況ドメインを関連付けることができます。

例10-15 新規作成された列への使用状況ドメインの関連付け

新規作成されたcustomers表の場合:

CREATE TABLE customers (
  cust_id NUMBER,
  cust_email VARCHAR2(100));

ADDを使用することで、新しい列のcust_new_emailを追加して、その列にemailドメインを関連付けできます。

ALTER TABLE customers
  ADD (cust_new_email VARCHAR2(100) DOMAIN email);

例10-16 email使用状況ドメインと既存の列の関連付け

MODIFYを使用することで、既存の列のcust_emailを変更して、その列にemailドメインを関連付けできます。

ALTER TABLE customers
  MODIFY (cust_email  VARCHAR2(100) DOMAIN email);

また、ALTER TABLE ... MODIFY文を使用して、列に使用状況ドメインを追加することもできます。次の例では、orders表の列であるorder_datetimeと、insert_timestampドメインのデフォルトが異なっています。insert_timestampドメインには、DEFAULTがありON NULL句が指定されていますが、order_datetime列にはありません。そのため、列にドメインを関連付けようとすると、エラーORA-11501: The column default does not match the domain default of the columnが発生します。

ALTER TABLE orders
  MODIFY order_datetime DOMAIN insert_timestamp;

このデフォルトの不一致を解決するために、ドメインのデフォルトと一致する列のdefault句を指定します。

ALTER TABLE orders
  MODIFY order_datetime DOMAIN insert_timestamp
    DEFAULT ON NULL systimestamp;

例10-17 関連付けられているドメインを表示するための問合せ

SELECT constraint_name, search_condition_vc, domain_constraint_name
  FROM  user_constraints
  JOIN  user_cons_columns
  USING ( constraint_name, table_name )
  WHERE  table_name = 'PEOPLE'
    AND  constraint_type = 'C'
    AND  column_name = 'WEIGHT_IN_KG';

出力は次のとおりです。


CONSTRAINT_NAME      SEARCH_CONDITION_VC            DOMAIN_CONSTRAINT_NAME   
-------------------- ------------------------------ --------------------------
SYS_C008493          "WEIGHT_IN_KG">0               POSITIVE_WEIGHT_C  

ガイドライン

  • ALTER TABLE .. ADD文のDOMAINキーワードは、新しく追加した列にドメインのみを指定する際のオプションです。

  • ALTER TABLE .. MODIFY文には、DOMAINキーワードが必須になります。

  • 列のデータ型には、ドメインのデータ型との互換性があることが必要です。

  • ドメインにデフォルトの式または照合がある場合は、関連付けられた列のデフォルトの式および照合と一致している必要があります。

  • 関連付けられる列にすでにドメインが関連付けられている場合は、エラーが返されます。

10.1.4.4 使用状況ドメインの変更

使用状況ドメインの表示式、順序式および注釈は変更可能です。サポートされているALTER DOMAIN DDL文は、次のとおりです。

例10-18 ドメインからの順序式の削除

height使用状況ドメイン定義にはVALUEという順序式があるため、順序式を削除するために、順序式をドロップする必要があります。

ALTER DOMAIN height DROP ORDER;

例10-19 使用状況ドメインへの表示式の追加

height使用状況ドメインに表示式を追加するには、次のALTERコマンドを使用します。

ALTER DOMAIN height 
  ADD DISPLAY round ( value ) || ' cm';

例10-20 birth_dateドメインの表示式の変更

birth_dateドメインの表示式を年数と月数に変更するには、次のALTERコマンドを使用します。

ALTER DOMAIN birth_date 
  MODIFY DISPLAY 
    FLOOR ( months_between ( sysdate, birth_date ) / 12 ) || ' years ' ||
    MOD ( FLOOR ( months_between ( sysdate, birth_date ) ), 12 ) || ' months';

例10-21 変更したbirth_dateheightおよびweightドメインについてのpeople表の問合せ

COLUMN age FORMAT A20

SELECT full_name, DOMAIN_DISPLAY ( date_of_birth ) age,
       DOMAIN_DISPLAY ( height_in_cm ) height_in_cm, weight_in_kg
  FROM  people
  ORDER  BY DOMAIN_ORDER ( height_in_cm );

関連項目:

DOMAIN_DISPLAYDOMAIN_ORDERなどのドメイン関数の詳細は、「ドメイン使用状況用のSQL関数」を参照してください。

出力は次のとおりです。

FULL_NAME            AGE                  HEIGHT_IN_CM  WEIGHT_IN_KG
-------------------- -------------------- ------------- ------------
Sally Squirell       42 years 5 months    180 cm                  61
Brian Badger         6 years 5 months     120 cm              27.181

例10-22 使用状況ドメインの注釈の変更

次のコードでは、height使用状況ドメインの注釈を追加します。

ALTER DOMAIN height
  ANNOTATIONS ( 
    operations '["insert", "update", "sort"]', 
    sensitive 'Private data');

例10-23 注釈の変更についてのディクショナリ・ビューの問合せ


COLUMN annotation_value FORMAT A40

SELECT column_name, annotation_name, annotation_value 
  FROM user_annotations_usage
  WHERE object_name = 'PEOPLE';

出力は次のとおりです。


COLUMN_NAME          ANNOTATION_NAME      ANNOTATION_VALUE                        
-------------------- -------------------- ----------------------------------------
PERSON_ID            PRIMARY_KEY          <null>                                  
PERSON_ID            MANDATORY            <null>                                  
PERSON_ID            OPERATIONS           ["insert", "delete"]                    
DATE_OF_BIRTH        SENSITIVE            PII Data                                
DATE_OF_BIRTH        OPERATIONS           ["insert", "update"]                    
HEIGHT_IN_CM         OPERATIONS           ["insert", "update"]                    
HEIGHT_IN_CM         OPERATIONS           ["insert", "update", "sort"]            
HEIGHT_IN_CM         SENSITIVE            Private data                            
WEIGHT_IN_KG         OPERATIONS           ["insert", "update"]                    

ガイドライン

  • ドメインの表示式は、そのドメインがフレキシブル・ドメインの構成要素でない場合にのみ変更できます。

  • ドメインの順序式は、そのドメインがフレキシブル・ドメインの構成要素でない場合にのみ変更できます。

  • ドメイン・レベルの注釈のみを変更できます。

関連項目:

  • 使用状況ドメインの変更に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: ALTER DOMAINを参照してください。

  • 使用状況ドメインのディクショナリ・ビューについては、「ドメイン情報の表示」を参照してください

10.1.4.5 列からの使用状況ドメインの関連付け解除

ALTER TABLE DDLは、DROP句とともに使用することで、列から使用状況ドメインの関連付けを解除できます。

例10-24 列からの使用状況ドメインの関連付け解除

customers表のcust_email列から関連付けられたドメインを削除するには:

ALTER TABLE customers
  MODIFY ( cust_email ) DROP DOMAIN;

ドメインを削除するが、ドメインの制約を維持するには:

ALTER TABLE customers
  MODIFY ( cust_email ) DROP DOMAIN PRESERVE CONSTRAINTS;

例10-25 列からの使用状況ドメインの関連付け解除

次のコードは、制約を維持しながら、people表のheight_in_cm列からheightドメインのドメイン関連付けを削除します。

ALTER TABLE people
  MODIFY ( height_in_cm ) DROP DOMAIN PRESERVE CONSTRAINTS;

例10-26 使用状況ドメインの関連付けが解除された列の問合せ

user_constraintsディクショナリ表に対するSELECT問合せによって、変更内容が表示されます。

SELECT constraint_name, search_condition_vc, domain_constraint_name
  FROM user_constraints
  JOIN user_cons_columns
  USING ( constraint_name, table_name )
  WHERE table_name = 'PEOPLE'
    AND constraint_type = 'C';

出力は次のとおりです。


CONSTRAINT_NAME      SEARCH_CONDITION_VC                      DOMAIN_CONSTRAINT_NAME       
-------------------- ---------------------------------------- ------------------------------
SYS_C009491          "DATE_OF_BIRTH"=TRUNC("DATE_OF_BIRTH")   BIRTH_DATE_ONLY_C            
SYS_C009494          "WEIGHT_IN_KG">0                         POSITIVE_WEIGHT_C            
SYS_C009489          "PERSON_ID" IS NOT NULL                  <null>                       
SYS_C009490          "HEIGHT_IN_CM">0                         <null>                       

例10-27 削除したheightドメインの再追加

次のコードでは、削除したheightドメインをpeople表のheight_in_cm列に再追加します。

ALTER TABLE people
  MODIFY ( height_in_cm ) ADD DOMAIN height;

例10-28 再追加したドメインの問合せ

再追加したheightドメインによって、重複するheight_in_cm > 0制約が作成されます。

SELECT constraint_name, search_condition_vc, domain_constraint_name
  FROM user_constraints
  JOIN user_cons_columns
  USING ( constraint_name, table_name )
  WHERE table_name = 'PEOPLE'
    AND constraint_type = 'C'
  ORDER BY search_condition_vc;

出力は次のとおりです。


CONSTRAINT_NAME      SEARCH_CONDITION_VC                      DOMAIN_CONSTRAINT_NAME       
-------------------- ---------------------------------------- ------------------------------
SYS_C009491          "DATE_OF_BIRTH"=TRUNC("DATE_OF_BIRTH")   BIRTH_DATE_ONLY_C            
SYS_C009495          "HEIGHT_IN_CM">0                         POSITIVE_HEIGHT_C            
SYS_C009490          "HEIGHT_IN_CM">0                         <null>                       
SYS_C009489          "PERSON_ID" IS NOT NULL                  <null>                       
SYS_C009494          "WEIGHT_IN_KG">0                         POSITIVE_WEIGHT_C 

ガイドライン

列のドメインを削除すると、デフォルトで次の項目が保持されます。

  • ドメインの照合。

  • 列に追加されているドメイン以外の制約。

ドメインのデフォルト値は保持されません。デフォルトが明示的に列に適用されている場合にのみ保持されます。

関連項目:

  • 使用状況ドメインの変更に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: ALTER DOMAINを参照してください。

  • 使用状況ドメインのディクショナリ・ビューについては、「ドメイン情報の表示」を参照してください

10.1.4.6 使用状況ドメインの削除

使用状況ドメインは削除できます。ドメインの削除の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

例10-29 使用状況ドメインの削除

次のcustomers表には、emailドメインに関連付けられている列が1つあります。

CREATE TABLE customers (
  cust_id NUMBER,
  cust_email VARCHAR2(100) DOMAIN email);

次のDROPコマンドは、customers表のcust_email列にemailドメインが関連付けられているため、エラーを返します。

DROP DOMAIN email;

次のDROPコマンドは成功します:

DROP DOMAIN email FORCE;

cust_email列はemailドメインからの関連付けが解除され、emailドメインにかかわる文のすべてが無効になります。

例10-30 制約が保持されるドメインの削除

次のDROPコマンドは成功しますが、デフォルト式と制約式は保持されます。

DROP DOMAIN email FORCE PRESERVE;

cust_email列にはON NULL email_seq.NEXTVAL || '@domain.com'が維持され、制約は制約内のドメイン名を列名に置き換えた後に保持されます: CONSTRAINT email_c CHECK (REGEXP_LIKE (cust_email, '^(\S+)\@(\S+)\.(\S+)$'))

ガイドライン

  • フレキシブル・ドメインで参照されているドメインを削除する場合は、FORCEオプションを指定したDROP DOMAINを使用します。

  • ドメインが表列に関連付けられていないときに、ドメインがフレキシブル・ドメインの構成要素でない場合、ドメインは削除されます。使用状況ドメインが使用中の場合、DROP文は失敗します。

  • ドメインがいずれかの表列に関連付けられている場合は、ドメインの削除にFORCEオプションを使用する必要があります。FORCEオプションを使用すると、次の作用が伴われます:

    • ドメインのデフォルトのみが設定されている場合は、デフォルトの式が削除されます。

    • ドメインと列の両方にデフォルトが設定されている場合は、列のデフォルト式が保持されます。

    • すべての関連付けられた列からドメインの注釈が削除されます。

    • ドメインに関連付けられた列の照合が保持されます。

    • カーソル・キャッシュ内のすべてのSQL依存文が無効になります。

    • FORCE PRESERVEが使用されている場合は、ドメインに関連付けられている列の制約が保持されます。

関連項目:

10.1.4.6.1 ドメインの削除とごみ箱について

削除された表は、ごみ箱に配置されます。ごみ箱内の表に関連付けられているドメインを削除するには、DROPコマンドにFORCEオプションを指定する必要があります。

ごみ箱内にある削除した表は、FLASHBACK TABLEコマンドを使用すると削除前の配置にリストアできます。関連付けられたドメインの削除後に、表が削除前の配置にリストア(FLASHBACK TABLE TO BEFORE DROP)されると、その表には削除前のものと同じデフォルト、照合、NULL値可能性および制約が保持されています。ただし、そうした属性はいずれもドメインから継承されたものとしてのマークがありません。

例10-31 削除した表に関連付けられている使用状況ドメインの削除

次のDROPコマンドでは、people表のweight_in_kg列に関連付けられているweightドメインの削除を試行します。


DROP DOMAIN weight;

このコマンドは次のエラー出力を返します:

ORA-11502: The domain WEIGHT to be dropped has dependent objects.

people表を削除してからweightドメインを削除すると、その表がごみ箱に残っているため、エラーが返されます。

DROP TABLE people;
DROP DOMAIN weight;

このコマンドは次のエラー出力を返します:

ORA-11502: The domain WEIGHT to be dropped has dependent objects.

ごみ箱からpeople表を完全に削除してから、weightドメインに対してDROPコマンドを実行すると、weightドメインが削除されます。


PURGE TABLE people;
DROP DOMAIN weight;

ガイドライン

削除した表(ごみ箱内の表)に関連付けられているドメインを削除する際には、次の点に注意してください。

  • 表がごみ箱にある間は、その表に対するALTERコマンドは許可されません。

  • ごみ箱にドメインに関連付けられている表がある場合は、関連付けられたドメインは削除できず、DROP DOMAINコマンドは失敗します。

  • DROP DOMAIN FORCEコマンドとDROP DOMAIN FORCE PRESERVEコマンドを使用すると、ごみ箱内の表のドメインからの関連付けが解除されます。データベースでは、FORCEのみを指定した場合でも、ごみ箱内の表に対してはFORCE PRESERVEセマンティクスが使用されます。

  • ごみ箱内の表に関連付けられているドメインを削除する場合は、ごみ箱から表を削除するためにPURGE TABLEコマンドを使用し、ドメインを削除するためにDROP DOMAINコマンドを実行します。

10.1.5 複数列使用状況ドメインの使用

この項では、複数列使用状況ドメインを作成、関連付け、変更、関連付け解除および削除する方法について説明します。

10.1.5.1 複数列使用状況ドメインの作成

複数列使用状況ドメインを使用して、表の列にまたがる住所などの論理エンティティをグループ化できます。

例10-32 住所用の複数列使用状況ドメインの作成

住所エントリ用に3つの列が含まれている"US_city"という複数列使用状況ドメインは、次のように作成できます。

CREATE DOMAIN US_city AS (
    name  AS VARCHAR2(30) ANNOTATIONS (Address),
    state AS VARCHAR2(2) ANNOTATIONS (Address),
    zip AS NUMBER ANNOTATIONS (Address)
  )
  CONSTRAINT City_CK CHECK(state in ('CA','AZ','TX') and zip < 100000)
  DISPLAY name||', '|| state ||', '||TO_CHAR(zip)
  ORDER state||', '||TO_CHAR(zip)||', '||name
  ANNOTATIONS (Title 'Domain Annotation');

例10-33 通貨用の複数列使用状況ドメインの作成

次のコードでは、貨幣価値を特定の通貨の金額として通貨コードと表示する、currencyという複数列使用状況ドメインを作成します。表示は値でソートされ(低から高)、その後で通貨コードでソートされます。

CREATE DOMAIN currency AS (
    amount  AS NUMBER,
    iso_currency_code  AS CHAR(3 CHAR)
  )
  DISPLAY iso_currency_code || TO_CHAR ( amount, '999,999,990.00' )
  ORDER TO_CHAR ( amount, '999,999,990.00' ) || iso_currency_code;

ガイドライン

  • 複数列使用状況ドメインの個別の列に、単一列使用状況ドメインと同じデータ型を設定できます。

  • 複数列使用状況ドメインの場合、異なるドメイン間での列の重複は許容されません。たとえば、表T(TC1、TC2、TC3、TC4)、ドメインD1(C1、C2)およびD2(C1、C2)の場合は、D1(TC1、TC2)とD2(TC2、TC3)のような関連付けはできません。

  • 同じ表内の列の複数の順序付きサブセットは、同じドメインに関連付けできます。たとえば、ドメインD1は、D1(TC1、TC2)とD1(TC3、TC4)のような関連付けができます。

  • 表には最大で1つのLONG列を含めることができますが、ドメインには複数のLONGデータ型の列を含めることができます。そのようなドメインは、DOMAIN_CHECK演算子を使用して複数のLONG列が関与するチェック条件を評価する場合に役立ちます。

関連項目:

10.1.5.2 表作成時の複数列使用状況ドメインの関連付け

CREATE TABLE DDL文を使用すると、新しく作成した列に複数列使用状況ドメインを関連付けることができます。

例10-34 US_cityドメインと複数の列の関連付け

customer表を作成して、その表の3つの列にUS_cityドメインを関連付けることができます。

CREATE TABLE customer(
  cust_id  NUMBER, 
  cust_name  VARCHAR2(30), 
  city_name  VARCHAR2(30), 
  state  VARCHAR2(2), 
  zip  NUMBER, 
  DOMAIN US_city(city_name, state, zip));

次の例では、ドメイン間でCITY列とSTATE列が重複しているため、エラーが返されます。

CREATE TABLE customer(
  cust_id  NUMBER, 
  cust_name  VARCHAR2(30), 
  city_name  VARCHAR2(30), 
  state  VARCHAR2(2), 
  zip  NUMBER, 
  DOMAIN US_city(city_name, state, zip),
  DOMAIN US_city(cust_name, state, zip));

次の例では、CITY_NAME列が繰り返されるため、同様にエラーが返されます。

CREATE TABLE customer(
  cust_id  NUMBER, 
  cust_name  VARCHAR2(30), 
  city_name  VARCHAR2(30), 
  state  VARCHAR2(2), 
  zip  NUMBER, 
  DOMAIN US_city(city_name, city_name, zip));

例10-35 currencyドメインと複数の列の関連付け

currencyドメインに関連付けられたtotal_paid列とcurrency_code列を保持するorder_items表を作成できます。

CREATE TABLE order_items (
  order_id INTEGER, product_id INTEGER,
  total_paid NUMBER(10, 2), currency_code char (3 CHAR ),
  DOMAIN currency ( total_paid, currency_code ));

ガイドライン

  • 実際のパラメータとしてドメインに渡される列名は一意であることが必要です。

  • ドメイン列は、名前が異なる表列に関連付けできます。

  • DOMAINキーワードは必須です。

10.1.5.2.1 複数列ドメインに関連付けられた列に対するDMLの使用

次に、複数列使用状況ドメインが関連付けられた新しく作成する表列に使用できるDML文の例をいくつか示します。

例10-36 関連付けられた列に対するDMLコマンドの使用

値を挿入して表を問い合せると、currencyドメインの表示式と順序式に基づいた結果が表示されます。

INSERT INTO order_items
VALUES (1, 1,    9.99, 'USD'),
       (2, 2,    8.99, 'GBP'),
       (3, 3,    8.99, 'EUR'),
       (4, 4, 1399,    'JPY'),
       (5, 5,  825,    'INR');
        
SELECT order_id, product_id, 
  DOMAIN_DISPLAY ( total_paid, currency_code ) amount_paid
  FROM order_items
  ORDER BY DOMAIN_ORDER ( total_paid, currency_code );

関連項目:

DOMAIN_DISPLAYDOMAIN_ORDERなどのドメイン関数の詳細は、「ドメイン使用状況用のSQL関数」を参照してください。

出力は次のとおりです。


  ORDER_ID PRODUCT_ID AMOUNT_PAID       
---------- ---------- ------------------
         3          3 EUR           8.99
         2          2 GBP           8.99
         1          1 USD           9.99
         5          5 INR         825.00
         4          4 JPY       1,399.00
10.1.5.3 複数列使用状況ドメインの既存の列との関連付け

ALTER TABLE DDL文は、MODIFY句またはADD句とともに使用することで、既存の列または既存の表に新しく追加された列に複数列使用状況ドメインを関連付けることができます。

例10-37 複数列使用状況ドメインの既存の列との関連付け

次の例では、US_cityドメインをcustomer表の3つの列に適用します。

ALTER TABLE customer
  MODIFY (city_name, state, zip) ADD DOMAIN US_city;

ノート:

ALTER TABLE .. MODIFY文には、DOMAINキーワードが必須になります。

10.1.5.4 複数列使用状況ドメインの変更

単一列使用状況ドメインの変更と同様に、複数列使用状況ドメインも変更できます。複数列使用状況ドメインでは、DISPLAYプロパティとORDERプロパティを変更できます。複数列ドメインの場合、現在時点では列レベルでの注釈の変更はサポートされていませんが、オブジェクト・レベルの注釈は変更できます。

例10-38 複数列使用状況ドメインの表示式と順序式の変更

次のALTER文では、currencyドメインの表示式を変更します。現在の表示式では、通貨コードと通貨値が表示されます。変更した表示式では、通貨値の後に通貨コードが表示されます。

ALTER DOMAIN currency
  MODIFY DISPLAY TO_CHAR ( amount, '999,990.00' ) || '-' || iso_currency_code;

次のALTER文では、currencyドメインの順序式を変更します。現在の順序式では、通貨値でソートされた後に通貨コードでソートされます。変更した順序式では、通貨コードでソートされた後に通貨値でソートされます。

ALTER DOMAIN currency
  MODIFY ORDER iso_currency_code || TO_CHAR ( amount, '999,990.00' );

例10-39 変更した複数列ドメインに関連付けられた表の問合せ

SELECT order_id, product_id,
  DOMAIN_DISPLAY ( total_paid, currency_code ) amount_paid
  FROM order_items
  ORDER BY DOMAIN_ORDER ( total_paid, currency_code );

出力は次のとおりです。


ORDER_ID    PRODUCT_ID    AMOUNT_PAID   
----------- ------------- ---------------
          3             3        8.99-EUR   
          2             2        8.99-GBP   
          5             5      825.00-INR   
          4             4    1,399.00-JPY   
          1             1        9.99-USD

関連項目:

10.1.5.5 列からの複数列使用状況ドメインの関連付け解除

ALTER TABLE DDL文は、DROP句とともに使用することで、列から複数列使用状況ドメインの関連付けを解除できます。

例10-40 複数列使用状況ドメインの関連付け解除の例

次のALTER TABLEコマンドは、customer表のcity_name列、state列およびzip列からUS_Cityドメインを削除します。

ALTER TABLE customer
  MODIFY(city_name, state, zip) DROP DOMAIN;

表Tの列(c1、c2、c3)がドメインDに関連付けられていて、その他の列セット(c4、c5、c6)もドメインDに関連付けられている場合は、すべての列のドメインを削除できます。

ALTER TABLE T
  MODIFY (c1, c2, c6, c5, c4, c3) DROP DOMAIN;

複数列ドメインに関連付けられている列のサブセットのみを削除することはできません。たとえば、表Tの場合は、c1列とc2列のみを削除すると、エラーが返されます:

ALTER TABLE T
  MODIFY (c1, c2) DROP DOMAIN;

例10-41 複数列使用状況ドメインの関連付け解除のその他の例

次のコードでは、order_items表のtotal_paid列とcurrency_code列からcurrencyドメインを削除します。


ALTER TABLE order_items
  MODIFY ( total_paid, currency_code ) DROP DOMAIN;

ガイドライン

  • 同じドメインに関連付けられている、同じ表内の列の複数の順序付きサブセットが存在していることがあります。複数列ドメインを削除する構文では、関連付けられた列のうち関連付けを解除する列のリストを指定する必要があります。

  • ドメイン名は指定できません。

  • ALTER TABLE ..DROP DOMAINALTER TABLE ..MODIFYには、その他のオプションを指定できません。

10.1.5.6 複数列使用状況ドメインの削除

複数列使用状況ドメインを削除する場合は、単一列使用状況ドメインに使用したものと同じ構文を使用します。

ガイドライン

  • フレキシブル・ドメインで参照されているドメインを削除する場合は、FORCEオプションを指定したDROP DOMAINを使用します。

関連項目:

  • 使用状況ドメインの削除に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: DROP DOMAINを参照してください

  • 使用状況ドメインの削除の詳細は、「使用状況ドメインの削除」を参照してください。

10.1.6 フレキシブル使用状況ドメインの使用

この項では、フレキシブル使用状況ドメインを作成、関連付け、関連付け解除および削除する方法について説明します。

ノート:

フレキシブル使用状況ドメインは変更できません。そのかわりに、表からフレキシブル・ドメインの関連付けを解除し、ドメインをDROPし、ドメインを再作成して、表との関連付けを再実行することはできます。

10.1.6.1 フレキシブル使用状況ドメインの作成

フレキシブルでない別のドメイン(単一列および複数列の使用状況ドメイン)を参照するフレキシブル使用状況ドメインを作成し、それらのいずれかのドメインをデータのコンテキストに応じて表列に適用できます。たとえば、各国の住所の書式を検証するための複数列ドメインを作成できます。表列は1つのドメインにのみ属することが可能です。そのため、データベースで行ごとの各国に対応する住所ドメインを使用できるようにするには、国ドメインにわたるフレキシブル・ドメインを作成します。判別式の列として国を使用して、フレキシブル・ドメインに列を関連付けます。各行には、対応する国ドメインの住所ルールを適用できます。

例10-42 温度測定用のフレキシブル使用状況ドメインの作成

次のコードでは、3つのcelciusfahrenheitkelvinというドメインから、temperatureというフレキシブル使用状況ドメインを作成します。それぞれの温度スケールに応じて作成されたドメインには、適切な絶対零度のチェックと表示式があります。フレキシブル・ドメインにはELSE句がないため、別の温度単位の値の挿入が可能ですが、そうした温度単位の温度値は制約されません。


CREATE DOMAIN celcius AS NUMBER
  CONSTRAINT abs_zero_c_c CHECK ( celcius >= -273.15 )
  DISPLAY celcius || ' °C';
   
CREATE DOMAIN fahrenheit AS NUMBER
  CONSTRAINT abs_zero_f_c CHECK ( fahrenheit >= -459.67 )
  DISPLAY fahrenheit || ' °F';
   
CREATE DOMAIN kelvin AS NUMBER
  CONSTRAINT abs_zero_k_c CHECK ( kelvin >= 0 )
  DISPLAY kelvin || ' K';

次のコードでは、温度単位に基づいて使用するドメインを選択するフレキシブル・ドメインを作成します。


CREATE FLEXIBLE DOMAIN temperature (
  temp
 ) CHOOSE DOMAIN USING ( units char(1) ) 
 FROM (
  CASE units
    WHEN 'C' THEN celcius ( temp )
    WHEN 'F' THEN fahrenheit ( temp )
    WHEN 'K' THEN kelvin ( temp )
  END);

例10-43 住所用のフレキシブル使用状況ドメインの作成

次のコードでは、米国とイギリス(英国)のアドレスを表す複数列使用状況ドメインと、その他の国に向けたデフォルトの住所ドメインを作成します。

/* US addresses */
CREATE DOMAIN us_address AS (
  line_1  AS VARCHAR2(255 CHAR) NOT NULL,
  town    AS VARCHAR2(255 CHAR) NOT NULL,
  state   AS VARCHAR2(255 CHAR) NOT NULL,
  zipcode AS VARCHAR2(10 CHAR) NOT NULL
 ) CONSTRAINT us_address_c check ( 
   REGEXP_LIKE ( zipcode, '^[0-9]{5}(-[0-9]{4}){0,1}$' ));
 
/* British addresses */
CREATE DOMAIN gb_address AS ( 
  street   AS VARCHAR2(255 CHAR) NOT NULL,
  locality AS VARCHAR2(255 CHAR),
  town     AS VARCHAR2(255 CHAR) NOT NULL,
  postcode AS VARCHAR2(10 CHAR) NOT NULL
 ) CONSTRAINT gb_postcode_c check (
   REGEXP_LIKE ( 
    postcode, '^[A-Z]{1,2}[0-9][A-Z]{0,1} [0-9][A-Z]{2}$' ));
   
/* Default address */
CREATE DOMAIN global_address AS ( 
  line_1   AS VARCHAR2(255) NOT NULL,
  line_2   AS VARCHAR2(255),
  line_3   AS VARCHAR2(255),
  line_4   AS VARCHAR2(255),
  postcode AS VARCHAR2(10)); 

次のコードでは、国コードに基づいて使用する複数列住所ドメインを選択するフレキシブル・ドメインを作成します。

CREATE FLEXIBLE DOMAIN address (
  line_1, line_2, line_3, line_4,
  postal_code      
 )
 CHOOSE DOMAIN USING ( country_code VARCHAR2(2 char) )
 FROM (
  CASE country_code
    WHEN 'GB' THEN gb_address ( line_1, line_2, line_3, postal_code )
    WHEN 'US' THEN us_address ( line_1, line_2, line_3, postal_code )
    ELSE global_address ( line_1, line_2, line_3, line_4, postal_code )
  END);

ノート:

フレキシブル・ドメインを作成するには、構成要素ドメインごとにEXECUTE権限が必要です。

関連項目:

使用状況ドメインの作成に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: CREATE DOMAINを参照してください

10.1.6.2 表作成時のフレキシブル使用状況ドメインの関連付け

CREATE TABLE DDLを使用すると、新しい表に新しく作成した列のセットにフレキシブル使用状況ドメインを関連付けできます。列のセットにフレキシブル・ドメインを追加するには、ドメインに関連付ける列のリストを(ドメインの列順序で)指定し、判別式として使用する列のリストを(フレキシブル・ドメインの判別式の列順序で)指定します。

例10-44 temperatureフレキシブル・ドメインと新しい表列の関連付け

temperatureフレキシブル・ドメインを使用するsensor_readings表を作成し、USINGキーワードで判別式の列を指定します。


CREATE TABLE sensor_readings (
  sensor_id integer, reading_timestamp TIMESTAMP,
  temperature_reading NUMBER,
  temperature_units   CHAR(1 CHAR),
  DOMAIN temperature ( temperature_reading )
    USING ( temperature_units ));

例10-45 addressフレキシブル・ドメインと新しい表列の関連付け

次のコードでは、addressesという新しい表を作成し、その表の列をaddressフレキシブル・ドメインに関連付けます。

CREATE TABLE addresses (
  line_1 VARCHAR2(255) NOT NULL,
  line_2 VARCHAR2(255),
  line_3 VARCHAR2(255),
  line_4 VARCHAR2(255),
  country_code   VARCHAR2(2 CHAR) NOT NULL,
  postal_code    VARCHAR2(10 CHAR), 
  DOMAIN address ( 
    line_1, line_2, line_3, line_4, postal_code)
    USING ( country_code ));

ノート:

キーワードのDOMAINUSINGは、フレキシブル・ドメインを関連付けするときには必須です。

10.1.6.2.1 フレキシブル・ドメインに関連付けられた列に対するDMLの使用

次に、フレキシブル使用状況ドメインが関連付けられた新しく作成する表列に対するDML文の例を示します。

例10-46 temperatureフレキシブル・ドメインに関連付けられた列に対するDMLコマンドの使用

INSERT INTO sensor_readings 
VALUES ( 1, timestamp'2023-06-08 12:00:00', 21.1, 'C' ),
       ( 1, timestamp'2023-06-08 12:05:00', 21.2, 'C' ),
       ( 1, timestamp'2023-06-08 12:10:00', 20.9, 'C' ),
       ( 2, timestamp'2023-06-08 12:00:00', 68.5, 'F' ),
       ( 2, timestamp'2023-06-08 12:05:00', 68.1, 'F' ),
       ( 2, timestamp'2023-06-08 12:10:00', 68.9, 'F' ),
       ( 3, timestamp'2023-06-08 12:00:00', 290.23, 'K' ),
       ( 3, timestamp'2023-06-08 12:05:00', 289.96, 'K' ),
       ( 3, timestamp'2023-06-08 12:10:00', 289.65, 'K' ),
       ( 4, timestamp'2023-06-08 12:00:00', 528.15, 'R' ),
       ( 4, timestamp'2023-06-08 12:05:00', 528.42, 'R' ),
       ( 4, timestamp'2023-06-08 12:10:00', 527.99, 'R' );

SELECT sensor_id, reading_timestamp,
  DOMAIN_DISPLAY ( temperature_reading, temperature_units ) temp
  FROM  sensor_readings;

関連項目:

DOMAIN_DISPLAYDOMAIN_ORDERなどのドメイン関数の詳細は、「ドメイン使用状況用のSQL関数」を参照してください。

出力は次のとおりです。

 SENSOR_ID READING_TIMESTAMP              TEMP                                       
---------- ------------------------------ -------------------------------------------
         1 08-JUN-2023 12.00.00.000000000 21.1 °C                                    
         1 08-JUN-2023 12.05.00.000000000 21.2 °C                                    
         1 08-JUN-2023 12.10.00.000000000 20.9 °C                                    
         2 08-JUN-2023 12.00.00.000000000 68.5 °F                                    
         2 08-JUN-2023 12.05.00.000000000 68.1 °F                                    
         2 08-JUN-2023 12.10.00.000000000 68.9 °F                                    
         3 08-JUN-2023 12.00.00.000000000 290.23 K                                   
         3 08-JUN-2023 12.05.00.000000000 289.96 K                                   
         3 08-JUN-2023 12.10.00.000000000 289.65 K 
         4 08-JUN-2023 12.00.00.000000000 <null>                                    
         4 08-JUN-2023 12.05.00.000000000 <null>                                    
         4 08-JUN-2023 12.10.00.000000000 <null> 

例10-47 範囲外制約エラー

次の値は、それぞれの温度スケールに対して範囲外制約エラーになります。


INSERT INTO sensor_readings 
  VALUES ( 1, timestamp'2023-06-08 12:15:00', -400, 'C' );

INSERT INTO sensor_readings 
  VALUES ( 2, timestamp'2023-06-08 12:15:00', -999, 'F' );

INSERT INTO sensor_readings 
  VALUES ( 3, timestamp'2023-06-08 12:15:00',   -1, 'K' );

例10-48 addressフレキシブル・ドメインに関連付けられた列に対するDMLの使用

-- Great Britian
INSERT INTO addresses ( line_1, line_3, country_code, postal_code ) 
  VALUES ( '10 Big street', 'London', 'GB', 'N1 2LA' );
 
-- United States
INSERT INTO addresses ( line_1, line_2, line_3, country_code, postal_code ) 
  VALUES ( '10 another road', 'Las Vegas', 'NV', 'US', '87654-3210' );  
 
-- Tuvalu
INSERT INTO addresses ( line_1, country_code ) 
  VALUES ( '10 Main street', 'TV' );  
 
SELECT * FROM addresses;

出力は次のとおりです。


LINE_1             LINE_2       LINE_3    LINE_4    COUNTRY_CODE    POSTAL_CODE  
------------------ ------------ --------- --------- --------------- -----------
10 Big street      <null>       London    <null>    GB              N1 2LA         
10 another road    Las Vegas    NV        <null>    US              87654-3210     
10 Main street     <null>       <null>    <null>    TV              <null> 

次のINSERTコマンドは、US郵便番号が含まれたUK住所を挿入しようとしているため、エラーを返します。

INSERT INTO addresses ( line_1, line_3, country_code, postal_code ) 
  VALUES ( '10 Big street', 'London', 'GB', '12345-6789' );
ORA-11534: check constraint (schema.SYS_C0010286) due to domain constraint schema.SYS_DOMAIN_C00639 of domain schema.ADDRESS violated

次のINSERTコマンドは、州の値のないUS住所を挿入しようとしているため、エラーを返します。

INSERT INTO addresses ( line_1, line_2, country_code, postal_code ) 
  VALUES ( '10 another road', 'Las Vegas', 'US', '87654-3210' ); 
ORA-11534: check constraint (schema.SYS_C0010289) due to domain constraint schema.SYS_DOMAIN_C00636 of domain schema.ADDRESS violated
10.1.6.3 フレキシブル・ドメインの既存の列との関連付け

ALTER TABLE DDLは、MODIFY句またはADD句とともに使用することで、既存の列または既存の表に新しく追加された列にフレキシブル使用状況ドメインを関連付けることができます。

例10-49

次のコードでは、temp_sensor_readingsという新しい表を作成します。

CREATE TABLE temp_sensor_readings (
  sensor_id integer, reading_timestamp TIMESTAMP,
  temperature_reading NUMBER,
  temperature_units   CHAR(1 CHAR));

次のコードでは、temperatureフレキシブル・ドメインをtemperature_readingという既存の列に関連付けます。

ALTER TABLE temp_sensor_readings
  MODIFY (temperature_reading, temperature_units)
  ADD DOMAIN temperature;

ガイドライン

  • DOMAINキーワードは、フレキシブル・ドメインを関連付けるときには必須です。

  • ALTER TABLE .. ADD文には、USINGキーワードが必須になります。

  • 複数のフレキシブル・ドメインには、ドメイン列としても判別式の列としても、同じ列を関連付けることはできません。

  • 同一のドメインに列を関連付けることはできませんが、別の列位置を関連付けできます。

10.1.6.4 列からのフレキシブル使用状況ドメインの関連付け解除

ALTER TABLE DDLは、DROP句とともに使用することで、列からフレキシブル使用状況ドメインの関連付けを解除できます。

例10-50

次のコードでは、temp_sensor_readings表からtemperatureドメインを削除します。

ALTER TABLE temp_sensor_readings
  MODIFY (temperature_reading, temperature_units) DROP DOMAIN;

ガイドライン

  • ドメイン名は不要です。これは、どの列がどのドメインに関連付けられているかをデータベースが認識していて、1つの列は1つのドメインにのみ関連付けできるためです。

  • ALTER TABLE ..DROP DOMAINALTER TABLE ..MODIFYには、その他のオプションを指定できません。

10.1.6.5 フレキシブル使用状況ドメインの削除

フレキシブル使用状況ドメインを削除する場合は、単一列使用状況ドメインに使用したものと同じ構文を使用します。

ガイドライン

  • フレキシブル・ドメインで参照されているドメインを削除する場合は、FORCEオプションを指定したDROP DOMAINを使用します。この操作により、フレキシブル・ドメインも削除されます。

  • フレキシブル・ドメインをFORCEモードで削除するには、構成要素のフレキシブル・ドメインを削除する権限が必要です。

関連項目:

  • 使用状況ドメインの削除に関する構文とセマンティックの詳細は、『Oracle Database SQL言語リファレンス』: DROP DOMAINを参照してください。

  • 使用状況ドメインの削除の詳細は、「使用状況ドメインの削除」を参照してください。

10.1.7 ドメインのデータ型の指定

ドメイン・データ型は、Oracleデータ型のいずれかになります。修飾ドメイン名は、修飾されたユーザー定義データ型やOracle組込み型と競合しないようにする必要があります。

列がドメインに関連付けられていて、列のデータ型が指定されていない場合は、ドメインのデータ型が、関連付けられた列のデフォルトのデータ型として使用されます。関連付けられた列にすでにデータ型がある場合は、その列のデータ型が使用されます。

ドメイン・データ型がSTRICT以外として定義されている場合、関連付けられた列のデータ型はドメイン・データ型との互換性のみが必要です。つまり、データ型は同じであることが必要ですが、長さ、精度およびスケールは異なっていてもかまいません。たとえば、strict以外のドメインの場合、VARCHAR2(10)のドメインは、どのVARCHAR2列にも関連付けできます。

ドメイン・データ型がSTRICTとして定義されている場合、関連付けられた列のデータ型はドメイン・データ型と互換性があり、ドメイン・データ型の長さ、精度およびスケールも一致している必要があります。

例10-51 列とドメイン・データ型の関連付け

次の例では、year_of_birthドメインとemail_domドメインを作成し、ドメインを列に関連付けて、ドメインと列のデータ型の互換性を示します。


DROP DOMAIN IF EXISTS year_of_birth;

CREATE DOMAIN year_of_birth AS NUMBER(4)
    CONSTRAINT CHECK ( (TRUNC(year_of_birth) = year_of_birth) AND (year_of_birth >= 1900) );


DROP DOMAIN IF EXISTS email_dom;

CREATE DOMAIN email_dom AS VARCHAR2(100)
    CONSTRAINT email_chk check (REGEXP_LIKE (email_dom, '^(\S+)\@(\S+)\.(\S+)$'));

DROP TABLE IF EXISTS newcustomers PURGE;
CREATE TABLE newcustomers (
  cust_Id NUMBER,
  cust_year_of_birth NUMBER(6) DOMAIN year_of_birth,
  cust_hq_email VARCHAR2(50),
  cust_office_email VARCHAR2(100),
  cust_rep_email VARCHAR2(100));

DESC newcustomers;

出力は次のとおりです。


 Name                          Null?    Type
 ----------------------------- -------- ----------------------------
 CUST_ID                                NUMBER
 CUST_YEAR_OF_BIRTH                     NUMBER(6) SH.YEAR_OF_BIRTH
 CUST_HQ_EMAIL                          VARCHAR2(50)
 CUST_OFFICE_EMAIL                      VARCHAR2(100)
 CUST_REP_EMAIL                         VARCHAR2(200)

cust_year_of_birth列は、Oracleデータ型のNumberとして定義されていて、year_of_birthドメインにも関連付けられるため、その列のデータ型が列に割り当てられます。cust_year_of_birth列は、year_of_birthドメインで定義されているすべてのプロパティ(制約、表示、順序付けのプロパティなど)を継承します。

次の例では、year_of_birthドメインに関連付けられた列があるukcustomers表を作成しますが、その列にはデータ型がありません:

CREATE TABLE ukcustomers (
  cust_Id NUMBER,
  cust_year_of_birth DOMAIN year_of_birth);

DESC ukcustomers;

出力は次のとおりです。


 Name                           Null?    Type
 ------------------------------ -------- ----------------------------
 CUST_ID                                 NUMBER
 CUST_YEAR_OF_BIRTH                      NUMBER(4) SH.YEAR_OF_BIRTH

ここでは、cust_year_of_birth列に、ドメインのデータ型NUMBER(4)が割り当てられています。

次の例では、DOMAINキーワードが省略されています。

CREATE TABLE incustomers (
  cust_id NUMBER,
  cust_year_of_birth year_of_birth);

DESC incustomers;

出力は次のとおりです。


 Name                          Null?    Type
 ----------------------------- -------- ----------------------------
 CUST_ID                                NUMBER
 CUST_YEAR_OF_BIRTH                     NUMBER(4) SH.YEAR_OF_BIRTH

列定義句では、ドメイン句はデータ型句を置き換えるか、その直後に続ける必要があります。

ドメイン列データ型がSTRICTとして定義されていない場合は、列の長さに関係なく、同じデータ型の列にドメインを関連付けできます。

次のALTERコマンドは成功します。これは、ドメインと列のデータ型が同じで、列の長さがSTRICT以外のドメインではチェックされないためです。

ALTER TABLE newcustomers
  MODIFY cust_hq_email DOMAIN email_dom;

ALTER TABLE newcustomers
  MODIFY cust_office_email DOMAIN email_dom;

ALTER TABLE newcustomers
  MODIFY cust_rep_email DOMAIN email_dom;

ドメイン列データ型がSTRICTとして定義されている場合、ドメイン関連付けは、列とドメインのデータ型が同じで長さも一致している場合にのみ機能します。


DROP DOMAIN IF EXISTS email_dom;

CREATE DOMAIN email_dom AS VARCHAR2(100) STRICT
  CONSTRAINT email_chk check (REGEXP_LIKE (email_dom, '^(\S+)\@(\S+)\.(\S+)$'));

次のALTERコマンドは成功します。

ALTER TABLE newcustomers
  MODIFY cust_office_email DOMAIN email_dom;

次のALTERコマンドは、列長とドメイン長が一致しないために失敗します。

ALTER TABLE newcustomers
  MODIFY cust_hq_email DOMAIN email_dom;

ALTER TABLE newcustomers
  MODIFY cust_rep_email DOMAIN email_dom;

表列データ型からSTRICT以外のドメイン列データ型への互換性

次の各項目は、互換性のある型を示します。ドメイン列の型に互換性があれば、任意の表列を関連付けできます。STRICT以外のドメインでは、表列とドメイン列に異なる長さ、精度およびスケールを設定できます。
  • NUMBERNUMER(p)NUMBER(p, s)NUMERICNUMERIC(p)NUMERIC(p, s)DECIMALDECIMAL(p)DECDEC(p)INTEGERINTSMALLINTFLOATFLOAT(p)REALDOUBLE_PRECISION

  • CHAR(L)CHAR(L CHAR)CHAR(L BYTE)CHARACTER(L CHAR)CHARACTER(L BYTE)CHARACTER(L)

  • NCHAR(L)NATIONAL CHARACTER(L)NATIONAL CHAR (L)

  • VARCHAR2(L)VARCHAR2(L CHAR)VARCHAR2(L BYTE)、CHAR VARYING(L CHAR)CHAR VARYING(L BYTE)CHAR VARYING(L)、CHARACTER VARYING(L CHAR)CHARACTER VARYING(L BYTE)CHARACTER VARYING(L)

  • NVARCHAR2(L)NATIONAL CHAR VARYING (L)NATIONAL CHARACTER VARYING (L)

  • TIMESTAMPTIMESTAMP(p)

  • TIMESTAMP WITH TIME ZONETIMESTAMP(p) WITH TIME ZONE

  • TIMESTAMP WITH LOCAL TIME ZONETIMESTAMP(p) WITH LOCAL TIME ZONE

  • INTERVAL YEAR TO MONTHINTERVAL YEAR(p) TO MONTH

  • INTERVAL DAY TO SECONDINTERVAL DAY(p) TO SECONDINTERVAL DAY TO SECOND(s)INTERVAL DAY(p) TO SECOND(s)

  • ROWIDUROWIDUROWID(p)

  • RAW(p)RAW(p)

表列データ型からSTRICTドメイン列データ型への互換性

次の各項目は、互換性のある型を示します。ドメイン列の型に互換性があれば、任意の表列を関連付けできます。STRICTドメインの場合、表列とドメイン列は、長さ、精度およびスケールについて完全に一致する必要があります。

  • NUMBER(*)NUMBER

  • 表列データ型とドメイン列データ型の精度が同じ場合、NUMBER(p, 0)NUMERIC(p)NUMERIC(p, 0)DECIMAL(p)DEC(p)

  • 表列データ型とドメイン列データ型の精度とスケールが同じ場合、NUMBER(p, s)NUMERIC(p, s)DECIMAL(p, s)DEC(p, s)

  • NUMBER(*,0)NUMERIC(*)NUMERIC(*,0)DEC(*)DEC(*,0)DECIMAL(*)DECIMAL(*,0)INTEGERINTSMALLINT

  • FLOAT(63)REAL

  • FLOATFLOAT(126)DOUBLE PRECISION

  • 列データ型とドメイン列データ型のサイズ(バイト単位)が同じ場合、CHAR(L CHAR)CHAR(L BYTE)CHARACTER (L)。たとえば、1文字が4バイトの場合、CHAR (4 BYTE)CHAR(1 CHAR)STRICTドメイン列に関連付けできます。

  • 列データ型とドメイン列データ型のサイズ(バイト単位)が同じ場合、NCHAR(L)NATIONAL CHARACTER(L)NATIONAL CHAR (L)

  • 列データ型とドメイン列データ型のサイズ(バイト単位)が同じ場合、VARCHAR2(L CHAR)VARCHAR2(L BYTE)CHARACTER VARYING (L)CHAR VARYING(L)

  • 列データ型とドメイン列データ型のサイズ(バイト単位)が同じ場合、NVARCHAR2(L)NATIONAL CHAR VARYING (L)NATIONAL CHARACTER VARYING (L)

  • TIMESTAMPTIMESTAMP(6)

  • TIMESTAMP WITH TIME ZONETIMESTAMP(6) WITH TIME ZONE

  • TIMESTAMP WITH LOCAL TIME ZONETIMESTAMP(6) WITH LOCAL TIME ZONE

  • INTERVAL YEAR TO MONTHINTERVAL YEAR(2) TO MONTH

  • INTERVAL DAY TO SECONDINTERVAL DAY(2) TO SECONDINTERVAL DAY TO SECOND(6)INTERVAL DAY(2) TO SECOND(6)

  • ROWIDUROWID(10)

  • UROWIDUROWID(4000)ROWID(4000)

表列データ型からドメイン列データ型への互換性

次の列データ型は、同等のドメイン列データ型とのみ互換性があります。たとえば、DATE列型は、DATEドメイン列型にのみ関連付けできます。

  • BINARY_FLOAT

  • BINARY_DOUBLE

  • DATE

  • BLOB

  • CLOB

  • NCLOB

  • BFILE

  • LONG

  • LONG RAW

  • JSON

データ型に基づいた表列と使用状況ドメインの関連付けのルール

ドメインのデータ型がVARCHAR2(L [CHAR|BYTE])の場合、各国語サポート(NLS)設定のセッション・レベルの長さセマンティクス値がNLS_LENGTH_SEMANTICSBYTEとして設定されているときには、Lのバイト数をLに対応する最大長(バイト単位)にします。

ドメインに列を関連付ける場合は、次のルールが適用されます:

  • ドメインがSTRICT以外として定義されている場合、そのドメインは任意のxバイトのデータ型VARCHAR2(x)の列に関連付けできます。STRICT以外のドメインの場合は、Lとxが異なっていてもかまいません。

  • ドメインがSTRICTとして定義されている場合、そのドメインは任意のxバイト = Lバイトのデータ型VARCHAR2(x)の列に関連付けできます。STRICTドメインの場合、L|x CHARを必要に応じてBYTESに変換した後でも、Lとxのバイト数は同じであることが必要です。

たとえば、ドメイン・データ型の指定がVARCHAR2 STRICTのときに、MAX_STRING_SIZESTANDARDの場合、そのドメインはL = 4000のVARCHAR2(L BYTE)データ型の列と関連付けできます。セッションの現在のNLS設定が、文字を表すために最大2バイトを必要とする場合、ドメインにはVARCHAR2(2000 CHAR)データ型の列を関連付けることができます。MAX_STRING_SEMANTICSEXTENDEDに変更されると、L = 32767のVARCHAR2(L BYTE)またはVARCHAR2(16383 CHAR)のデータ型の列をドメインに関連付けできます。

同様のルールはNVARCHAR2(L)CHAR(L [CHAR|BYTE])およびNCHAR(L)にも適用されます。

10.1.8 使用状況ドメインのプロパティの変更

アプリケーションの進化につれて、列定義の変更が必要になることがあり、それに伴って関連する使用状況ドメインのプロパティの変更も必要になります。ドメインの変更時には、ドメインの注釈、表示式および順序式のみを変更できます。次に、ドメインのその他のプロパティを変更する方法を示します。

これらの例は、開始手段として利用することも、特定のデータとビジネスの要件にあわせて構築して適応させることもできます。最初の例では手動の方法を示し、その次の例ではdbms_redefinitionパッケージを使用したオンラインの方法を示します。

例10-52 ドメイン・プロパティの手動変更

電子メール・ドメイン・フィールドの文字列長を100から200に変更するとします。この変更を実施するには、次のステップを完了する必要があります。

  • 関連付けられた列の文字列長を200に変更します。

  • 列に関連付けられている現在のドメインを削除します。

  • 電子メールの文字列長が200の新しいドメインを作成します。

  • 現在のドメインに関連付けられていた列を新しいドメインに再関連付けします。

現在のドメイン定義と列の関連付けが次の場合:

CREATE DOMAIN email_dom AS VARCHAR2(100)
  CONSTRAINT email_chk CHECK (regexp_like (email_dom, '^(\S+)\@(\S+)\.(\S+)$'));

CREATE TABLE t1 (
  id NUMBER,
  email DOMAIN email_dom
);

ドメインに関連付けられている列のリストを表示するには:

SELECT table_name, column_name
  FROM user_tab_columns
  WHERE domain_name = 'EMAIL_DOM';

TABLE_NAME              COLUMN_NAME
---------------------- -------------------
T1                      EMAIL

t1表を変更して、電子メール列の文字列サイズを200に変更します。

ALTER TABLE t1 modify email varchar2(200);

FORCE PRESERVEオプションを指定してドメインを削除します:

DROP DOMAIN email_dom FORCE PRESERVE;

その後で、電子メールの文字列サイズが200の新しいドメインを作成します。

CREATE DOMAIN email_dom AS VARCHAR2(200)
  CONSTRAINT email_chk CHECK (regexp_like (email_dom, '^(\S+)\@(\S+)\.(\S+)$'));

さらに、新しいドメインを電子メール列に再関連付けします:

ALTER TABLE t1
  MODIFY email DOMAIN email_dom;

例10-53 オンラインのdbms_redefinitionパッケージを使用したドメイン・プロパティの変更

Oracleオンライン表再編成パッケージのdbms_redefinitionを使用すると、サポートされている通貨の更新などの許可された値を変更できます。たとえば、通貨ドメインでサポートされている通貨を変更するために必要なステップは次のとおりです:

  • 新しいドメインの作成

  • 新しいドメインを使用するように、現在のドメインに関連付けられていた列を移行します。

次の例には、基本的なエラー処理のみが含まれています。新しい制約に一部のデータが違反している場合など、複数の表の移行後にエラーが発生することがあります。完全なソリューションでは、このようなシナリオを考慮する必要があります。

次のコードでは、USD、GBPおよびEURの通貨を許容する制約があるドメインを作成します。

CREATE DOMAIN currency AS (
  amount AS NUMBER,
  iso_currency_code AS CHAR ( 3 CHAR )
 ) CONSTRAINT supported_currencies_c 
    CHECK ( iso_currency_code in ( 'USD', 'GBP', 'EUR' ) );

次の表には、currencyドメインに関連付けられた列があるとします。

CREATE TABLE order_items (
  order_id   INTEGER, product_id INTEGER,
  total_paid NUMBER(10, 2), currency_code CHAR ( 3 CHAR ),
  DOMAIN currency ( total_paid, currency_code ),
  PRIMARY KEY ( order_id, product_id )
);
        
CREATE TABLE product_prices (
  product_id    INTEGER,
  unit_price    NUMBER(10, 2), 
  currency_code CHAR( 3 char ),
  DOMAIN currency ( unit_price, currency_code ),
  PRIMARY KEY ( product_id, currency_code )
);

INSERTコマンドを使用して、product_prices表とorder_items表に、いくつかの値を格納します。

INSERT INTO product_prices
VALUES (1, 9.99, 'USD'),
       (1, 8.99, 'GBP'),
       (1, 8.99, 'EUR');
 
INSERT INTO order_items
VALUES (1, 1, 9.99, 'USD'),
       (2, 1, 8.99, 'GBP'),
       (3, 1, 8.99, 'EUR');
        
COMMIT;

ビジネスが拡大していて、さらに多くの通貨のサポートが必要になったとします。制約の直接的な変更はできないため、次のような代替方法が必要です。

  • 新しいドメインの作成。

  • 制約を保持しながら関連付けられている列から既存のドメインを削除するための、product_prices表とorder_items表の変更。

  • 新しいドメインを追加するための表の変更。

  • 表からの保持した制約の削除。

ただし、これらはオンラインで実行すると、DDL文をブロックします。そのかわりに、dbms_redefinitionパッケージを使用すると、オンラインで制約を変更できます。

新しくサポートされた通貨が含まれている制約によって新規ドメインを作成し、そのドメインを一時表に関連付ける必要があります。新しいドメインで元のドメインを置き換えます。


CREATE DOMAIN currency_d as (
  amount            AS NUMBER,
  iso_currency_code AS CHAR ( 3 CHAR )
 ) CONSTRAINT supported_currencies_d_c 
  CHECK ( iso_currency_code in ( 'USD', 'GBP', 'EUR', 'CAD', 'MXP', 'INR', 'JPY' ) );
   
CREATE TABLE order_items_tmp (
  order_id   INTEGER, product_id INTEGER,
  total_paid NUMBER(10, 2), currency_code CHAR ( 3 CHAR ),
  DOMAIN currency_d ( total_paid, currency_code ) ,
  PRIMARY KEY ( order_id, product_id )
);
        
CREATE TABLE product_prices_tmp (
  product_id    INTEGER,
  unit_price    NUMBER(10, 2), 
  currency_code CHAR (3 CHAR),
  DOMAIN currency_d ( unit_price, currency_code ),
  PRIMARY KEY ( product_id, currency_code )
);

このコードの再利用性を高めるために、redefine_tableプロシージャを作成します。このプロシージャでは、dbms_redefinitionプロシージャをコールすることで、一時表の列のプロパティを現在の表列にコピーして、現在の表列を新しいドメインにスワップします。

 
DECLARE
   
  PROCEDURE redefine_table ( current_table VARCHAR2, staging_table VARCHAR2 ) AS
    num_errors pls_integer;
  BEGIN
    DBMS_REDEFINITION.CAN_REDEF_TABLE(user, current_table);    
    DBMS_REDEFINITION.START_REDEF_TABLE(user, current_table, staging_table);
   
    DBMS_REDEFINITION.copy_table_dependents(
      uname               => user,
      orig_table          => current_table,
      int_table           => staging_table,
      copy_constraints    => false,
      num_errors          => num_errors);
     
    IF num_errors > 0 THEN
      dbms_redefinition.abort_redef_table(user, current_table, staging_table);
      raise_application_error ( -20001, num_errors || ' errors copying dependents from ' || current_table || ' to ' || staging_table );
    ELSE 
      dbms_redefinition.finish_redef_table(user, current_table, staging_table);
    END IF;
  END redefine_table;
 
BEGIN 
   
  FOR tabs IN ( 
    SELECT distinct table_name from user_tab_cols
    WHERE  domain_name = 'CURRENCY'
  ) LOOP
    redefine_table(tabs.table_name, tabs.table_name || '_TMP');
  END LOOP;
 
END;
/

product_prices表にDMLを使用して、新しい通貨が現在サポートされているかどうかを確認します。

-- New currencies now supported
INSERT INTO product_prices
  VALUES (1, 9.99, 'CAD');
 
-- Invalid currencies raise exception
INSERT INTO product_prices
  VALUES (1, 9.99, 'N/A');
 
SELECT * FROM product_prices;

出力は次のとおりです。

PRODUCT_ID UNIT_PRICE CUR
---------- ---------- ---
         1       9.99 USD
         1       8.99 GBP
         1       8.99 EUR
         1       9.99 CAD
 

一時オブジェクトと古いドメインcurrencyをクリーン・アップします。

DROP TABLE order_items_tmp PURGE;
DROP TABLE product_prices_tmp PURGE;
DROP DOMAIN currency;

関連項目:

『PL/SQLパッケージおよびタイプ・リファレンス』ガイドの「DBMS_REDEFINITION

10.1.9 使用状況ドメイン用のSQL関数

ドメイン関数を使用すると、より効率的に使用状況ドメインを操作できます。

使用状況ドメインには、次のSQL関数を使用できます。

  • DOMAIN_DISPLAYは、引数が関連付けられているドメインのドメイン表示式を返します。

  • DOMAIN_NAMEは、引数が関連付けられているドメインの修飾ドメイン名を返します。ドメインに対するパブリック・シノニムがある場合は、そのシノニムが返されます。それ以外の場合は、domain_owner.domain_nameの形式でドメイン名が返されます。

  • DOMAIN_ORDERは、引数が関連付けられているドメインのドメイン順序式を返します。

  • DOMAIN_CHECK(domain_name, value1, value2, ...)は、domain_nameの制約条件(NOT NULLまたはCHECK制約)をvalue式に適用します。さらに、値の型互換性もチェックします。値は多数になる可能性があります。値式の数はドメイン内の列の数と一致する必要があります。一致していないと文でエラーが発生します。

  • DOMAIN_CHECK_TYPE(domain_name, value1, value2, ...)では、入力式がドメインのデータ型と互換性があるかどうかを検証します。値は多数になる可能性があります。値式の数はドメイン内の列の数と一致する必要があります。一致していないと文でエラーが発生します。

関連項目:

使用状況ドメインでのSQL関数の使用の詳細は、『Oracle Database SQL言語リファレンス』ドメイン関数を参照してください

10.1.10 ドメイン情報の表示

ディクショナリ・ビューを使用すると、ドメインに関する情報を取得できます。ディクショナリ・ビューは、関連付けられたドメインと比較したときに、制約やデフォルト式などのプロパティが異なる列の識別にも役立ちます。

10.1.10.1 使用状況ドメインのディクショナリ・ビュー

ディクショナリ・ビューの[USER|DBA|ALL]_DOMAINS[USER|DBA|ALL]_DOMAIN_COLSはドメインを表し、ドメイン列に関する次の情報を提供します。フレキシブル・ドメインの場合は、ドメイン・セレクタ式もビューに含まれます。

  • ドメイン名

  • ドメイン所有者

  • 表示式と順序式

  • デフォルト値

  • ドメインのデータ型

  • 照合

使用状況ドメインには、次のディクショナリ・ビューを使用できます。

  • ALL_DOMAINSは、現行のユーザーがアクセスできるドメインを示します。

  • DBA_DOMAINSは、データベース内のすべてのドメインを示します。

  • USER_DOMAINSは、現行のユーザーが所有するドメインを示します。

  • ALL_DOMAIN_COLSは、現行のユーザーがアクセスできるドメインの列を示します。

  • DBA_DOMAIN_COLSは、データベース内のすべてのドメインの列を示します。

  • USER_DOMAIN_COLSは、現行のユーザーが所有するドメインの列を示します。

  • ALL_DOMAIN_CONSTRAINTSは、現行のユーザーがアクセスできるドメインの制約定義を示します。

  • DBA_DOMAIN_CONSTRAINTSは、データベース内のすべてのドメインの制約定義を示します。

  • USER_DOMAIN_CONSTRAINTSは、現行のユーザーが所有するドメインの制約定義を示します。

関連項目:

使用状況ドメインに使用されるビューの詳細は、『Oracle Databaseリファレンス』のビューALL_DOMAINSDBA_DOMAINSUSER_DOMAINSALL_DOMAIN_COLSDBA_DOMAIN_COLSUSER_DOMAIN_COLSALL_DOMAIN_CONSTRAINTSDBA_DOMAIN_CONSTRAINTSUSER_DOMAIN_CONSTRAINTSを参照してください。

10.1.11 組込みの使用状況ドメイン

Oracle Databaseには、表列に直接使用できる組込みの使用状況ドメイン(email_d、ssn_d、credit_card_number_dなど)が用意されています。組込みの使用状況ドメインは、すべてのPDBに存在しています。新しいPDBがCDBに追加されると、組込みの使用状況ドメインが自動的に作成されてPDBに追加されます。

次に、Oracle Databaseでサポートされている、すべての組込みの使用状況ドメインのリストを示します。

表10-1 組込みのドメイン

名前 指定可能な値 説明:

email_d

^([a-zA-Z0-9!#$%&*+=?^_`{|}~-]+(\.[ A-Za-z0-9!#$%&*+=?^_`{|}~-]+)*)@(([ a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9] )?\.)+[a-zA-Z0-9]([a-zA-Z0-9-]*[a-z A-Z0-9])?)$

電子メール・アドレス

実装: Regex

day_short_d

'MON'、'TUE'、'WED'、'THU'、'FRI'、'SAT'、'SUN'

短い形式での曜日

ドメイン順序: nls_territory値に基づきます

実装: List

day_d

'MONDAY'、'TUESDAY'、'WEDNESDAY'、'THURSDAY'、'FRIDAY'、'SATURDAY'、'SUNDAY'

長い形式での曜日

ドメイン順序: nls_territory値に基づきます

実装: List

month_short_d

'JAN'、'FEB'、'MAR'、'APR'、'MAY'、'JUN'、'JUL'、'AUG'、'SEP'、'OCT'、'NOV'、'DEC'

短い書式での月

実装: List

month_d

'JANUARY'、'FEBRUARY'、'MARCH'、'APRIL'、'MAY'、'JUNE'、

'JULY'、'AUGUST'、'SEPTEMBER'、'OCTOBER'、'NOVEMBER'、'DECEMBER'

長い書式での月

実装: List

year_d

year > 0とyear <= 9999

年(0-9999)

実装: Check

positive_number_d

positive_number > 0

正の数値: 1、2、3、4、...

実装: Check

negative_number_d

negative_number < 0

負の数値: ...、-3、-2、-1

実装: Check

non_positive_number_d

non_positive_number <= 0

正でない数値: ...、-3、-2、-1、0

実装: Check

non_negative_number_d

non_negative_number >= 0

負でない数値: 0、1、2、3...

実装: Check

mac_address_d

^([a-fA-F0-9]{2}[-]){5}[a-fA-F0-9]{2}$

^([a-fA-F0-9]{2}[:]){5}[a-fA-F0-9]{2}$

MACアドレス

実装: regex

ssn_d

^[0-9]{3}[-][0-9]{2}[-][0-9]{4}$

US SSN

実装: regex

credit_card_number_d

^([0-9]{4}[-]){3}[0-9]{4}$

^([0-9]{4}[ ]){3}[0-9]{4}$

^([0-9]{4}){3}[0-9]{4}$

^[0-9]{4}[-][0-9]{6}[-][0-9]{5}$

^[0-9]{4}[ ][0-9]{6}[ ][0-9]{5}$

^[0-9]{15}$

クレジット・カード番号

実装: regex

ipv4_address_d

^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$

IPv4アドレス

実装: regex

ipv6_address_d

^([0-9a-fA-F]{4}[:]){7}[0-9a-fA-F]{4}$

^([0-9a-fA-F]{4}[:]){6}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$

IPv6アドレス

実装: regex

subnet_mask_d

^(((255\.){3}(255|254|252|248|240|224|192|128|0))|((255\.){2}(255|254|252|248|240|224|192|128|0)\.0)|

((255\.)(255|254|252|248|240|224|192|128|0)(\.0+){2})|((255|254|252|248|240|224|192|128|0)(\.0){3}))$

サブネット・マスク

実装: regex

sha1_d

^[0-9a-fA-F]{40}$

SHA1

実装: regex

sha256_d

^[0-9a-fA-F]{64}$

SHA256

実装: regex

sha512_d

^[0-9a-fA-F]{128}$

SHA512

実装: regex

cidr_d

^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2][0-9]|3[0-2])$

CIDR

実装: regex

phone_number_d

^[+]{0,1}[0-9]{1,16}$

電話番号

実装: regex

mime_type_d

'application/epub+zip',

'application/gzip',

'application/java-archive',

'application/json',

'application/ld+json',

'application/msword',

'application/msword',

'application/ogg',

'application/pdf',

'application/rtf',

'application/vnd.amazon.ebook',

'application/vnd.apple.installer+xml'、

'application/vnd.ms-excel',

'application/vnd.ms-fontobject',

'application/vnd.ms-powerpoint',

'application/vnd.oasis.opendocument.presentation',

'application/vnd.oasis.opendocument.spreadsheet',

'application/vnd.oasis.opendocument.text',

'application/vnd.openxmlformats-officedocument.presentationml.presentation',

'application/vnd.openxmlformats-officedocument.wordprocessingml.document',

'application/vnd.rar',

'application/vnd.visio',

'application/x-abiword',

'application/x-bzip',

'application/x-bzip2',

'application/x-cdf',

'application/x-compressed',

'application/x-csh',

'application/x-freearc',

'application/x-httpd-php',

'application/x-sh',

'application/x-shockwave-flash',

'application/x-tar',

'application/x-zip-compressed',

'application/zip',

'audio/aac',

'audio/midi',

'audio/mpeg',

'audio/ogg',

'audio/opus',

'audio/wav',

'audio/webm',

'audio/x-midi',

'font/otf',

'font/ttf',

'image/avif',

'image/bmp',

'image/gif',

'image/jpeg',

'image/png',

'image/svg+xml',

'image/tiff',

'image/vnd.microsoft.icon',

'text/calendar',

'text/css',

'text/csv',

'text/html',

'text/javascript',

'text/javascript',

'text/plain',

'video/mp2t',

'video/mp4',

'video/mpeg',

'video/ogg',

'video/webm',

'video/x-msvideo'

MIMEタイプ

実装: list

10.2 アプリケーション使用状況の注釈

この項では、データベース・オブジェクトにアプリケーション使用状況の注釈(以降は、「注釈」と表記)を使用する方法について説明します。

多くのアプリケーションでは、表、ビュー、表の列、索引、ドメインなどのデータベース・オブジェクトに関する追加のプロパティ・メタデータを保持することが重要です。注釈を使用すると、アプリケーションで、データベース・オブジェクトおよび表の列に関するユーザー固有のメタデータをさらに格納および取得できます。アプリケーションでは、このようなメタデータを使用して、効果的なユーザー・インタフェースをレンダリングしたり、アプリケーション・ロジックをカスタマイズできます。

10.2.1 注釈の概要

注釈とは何ですか。また、どこで使用できますか。

注釈は、開発者がデータベース・スキーマ・オブジェクトの使用状況プロパティを一元的に登録するための軽量な宣言機能です。注釈はディクショナリ表に格納され、関連アプリケーションの共通データ全体にわたって動作の標準化を求めるアプリケーションで使用できます。注釈はデータベースによって解釈されません。これらはデータベース・メタデータのカスタム・データ・プロパティであり、表の列、表および索引に含まれており、アプリケーションは追加のプロパティ・メタデータとして使用してユーザー・インタフェースをレンダリングしたり、アプリケーション・ロジックをカスタマイズできます。

アプリケーション・メタデータをデータベースに一元的に定義および格納するメカニズムである注釈を使用すると、アプリケーション、モジュールおよびマイクロサービス間でメタデータ情報を共有できます。新しいオブジェクトを(CREATE文を使用して)作成したり、既存のオブジェクトを(ALTER文を使用して)変更するときに、注釈をスキーマ・オブジェクトに追加できます。

メタデータを使用してデータ・モデルに注釈を付けると、データの整合性と一貫性が向上し、データ・モデルのドキュメンテーションのメリットが高まります。アプリケーションでは、他のアプリケーションまたはユーザーが取得および使用できるデータベース・オブジェクトと表の列に関するユーザー定義のメタデータを格納できます。データとともにメタデータを格納すると、データを使用するユーザーまたはアプリケーションに対する一貫性と汎用的なアクセシビリティが保証されます。

個々の注釈には名前とオプションの値があります。名前とオプションの値は自由形式のテキスト・フィールドです。たとえば、名前と値のペアを持つ注釈(Display_Label 'Employee Salary'など)を保持したり、名前のみを持つ(名前が説明なしでわかるため値が不要の)スタンドアロンの注釈(UI_Hiddenなど)を保持できます。

次に、注釈の詳細を示します。

  • CREATE DDL文を使用してスキーマ・オブジェクトに注釈名を指定すると、注釈が自動的に作成されます。

  • 注釈は付加的です。つまり、同じスキーマ・オブジェクトに複数の注釈を指定できます。

  • 1つのDDL文を使用して、一度に複数の注釈をスキーマ・オブジェクトに追加できます。同様に、1つのDDL文で複数の注釈をスキーマ・オブジェクトから削除できます。

  • 注釈は、注釈を追加するデータベース・オブジェクトに対する下位要素として表されます。注釈は、データベース内に新しいオブジェクト・タイプを作成しません。

  • 自分が所有しているか、スキーマ・オブジェクトに対する変更権限あれば、注釈をサポートする任意のスキーマ・オブジェクトに注釈を追加できます。注釈名をスキーマ修飾する必要はありません。

  • ディクショナリ・ビューに対してSQL問合せを発行して、名前と値およびスキーマ・オブジェクトでの使用を含め、すべての注釈を取得できます。

10.2.2 注釈とコメント

COMMENTコマンドを使用して、表や表の列などのデータベース・オブジェクトに注釈を付けることもできます。スキーマ・オブジェクトに関連付けられたコメントは、オブジェクトのメタデータとともにデータ・ディクショナリに格納されます。

注釈は、コメントよりも使用しやすく、範囲が広くなります。コメントと注釈の主な違いは次のとおりです。

  • コメントは、表や列などの特定のスキーマ・オブジェクトにのみメタデータを追加するために使用されるコメント・メカニズムです。索引、プロシージャ、トリガー、ドメインなど、他のスキーマ・オブジェクトではコメントを使用できません。

  • コメントには名前がなく、自由形式の値しかありません。

  • コメントは付加的ではありません。つまり、同じオブジェクトに複数のコメントを追加することはできません。新しいコメントを指定すると、対応する表または列に関する前のコメントが上書きされます。

  • コメントには別々のDDL文が必要であるのに対し、複数の注釈を結合して1つのDDL文にできます。

  • エンティティごとに個別のディクショナリ・ビュー・セットが存在します。たとえば、表コメント用のビューと列コメント用の別のビューがあります。一方、注釈は、すべてのオブジェクト・タイプで統一されているため、問合せおよび使用が簡単になります。

関連項目:

COMMENTSの使用方法の詳細は、コメントを参照してください。

10.2.3 サポートされているデータベース・オブジェクト

注釈は、次のデータベース・オブジェクトでサポートされています。

  • 表および表の列

  • ビューおよびビューの列

  • マテリアライズド・ビューおよびマテリアライズド・ビューの列

  • 索引

  • ドメインおよび複数列ドメインの列

10.2.4 注釈の使用に必要な権限

注釈を追加または削除するには、CREATEまたはALTER DDL文で注釈が指定されているスキーマ・オブジェクトに対するCREATEまたはALTER権限が必要です。

注釈を明示的に作成または削除することはできません。注釈は、初回使用時に自動的に作成されます。注釈は、注釈が定義されているデータベース・オブジェクト内の下位要素として格納されるため、注釈を追加してもデータベース内に新しいオブジェクト・タイプは作成されません。

10.2.5 注釈のDDL文

この項では、注釈の構文について説明し、表、表の列、ビュー、マテリアライズド・ビュー、索引およびドメインの注釈を定義または変更するためのDDL文を示します。

トピック:

10.2.5.1 注釈の構文

次のスニペットは、表、表の列、ビュー、マテリアライズド・ビュー、索引およびドメインの注釈を定義するためにDDL文で使用される注釈の構文を示しています。

annotations
         ::= 'ANNOTATIONS' '(' annotations_list ')'

annotations_list
         ::= ( 'ADD' ('IF NOT EXISTS' | 'OR REPLACE' )? | 'DROP' 'IF EXISTS'? | REPLACE)?
 annotation ( ',' ( 'ADD' ('IF NOT EXISTS' | 'OR REPLACE' )? | 'DROP' 'IF EXISTS'? | REPLACE)?
 annotation )*

annotation
         ::= annotation_name annotation_value?

annotation_name
         ::= identifier

annotation_value
         ::= character_string_literal

<annotation_value>は、最大4000文字を保持できる文字列リテラルです。

<annotation_name>は識別子であり、次の要件があります。

  • 識別子は1024文字まで指定できます。

  • 識別子が予約語である場合は、注釈名を二重引用符で囲む必要があります。

  • 二重引用符で囲まれた識別子には、空白文字を含めることができます。

  • 空白文字のみが含まれる識別子は使用できません。

10.2.5.2 表に注釈を付けるDDL文

次のDDL文を使用して、表を作成または変更するときに表に注釈を付けることができます。

CREATE TABLE文の使用方法

次に、注釈を指定したCREATE TABLE文の例を示します。

次の例では、JSON値の注釈Operationと、もう1つのスタンドアロンで値のない注釈Hiddenを追加します。

CREATE TABLE Table1 (
  T NUMBER)
  ANNOTATIONS(Operations '["Sort", "Group"]', Hidden);

注釈をするときには、その前にADDキーワードを使用できます。すべての指定を省略すると、ADDキーワードがデフォルトの操作とみなされます。

次の例では、オプションのADDキーワードを使用して、Hidden注釈(同様にスタンドアロン)をTable2に追加します。

CREATE TABLE Table2 (
  T NUMBER)
  ANNOTATIONS (ADD Hidden);

ADDキーワードは、注釈を定義するときの暗黙的な操作であり、省略できます。

ALTER TABLE文の使用方法

次の例では、ALTER TABLEコマンドによって、注釈名OperationsおよびHiddenのすべての注釈値が削除されます。

ALTER TABLE Table1
  ANNOTATIONS(DROP Operations, DROP Hidden);

次の例のALTER TABLEコマンドでは、Join値の注釈JoinOperationsを追加して、注釈名Hiddenを削除します。注釈を削除するときには、DROPコマンドに注釈名のみを含める必要があります。

ALTER TABLE Table1
  ANNOTATIONS(ADD JoinOperations 'Join', DROP Hidden);

1つのDDL文に複数のADDおよびDROPキーワードを指定できます。

同じオブジェクト(オブジェクト・レベルの注釈の場合)または同じ列(列レベルの注釈の場合)に、値が異なる注釈を再追加しようとするとエラーが発生します。たとえば、次の文は失敗します:
ALTER TABLE Table1
  ANNOTATIONS(ADD JoinOperations 'Join Ops');

出力は次のとおりです。

ORA-11552: Annotation name 'JOINOPERATIONS' already exists.
そのかわりとして、注釈構文では、REPLACEキーワードを使用して注釈値を置換できます。次の文では、JoinOperationsの値を'Join Ops'に置き換えます:
ALTER TABLE Table1
  ANNOTATIONS(REPLACE JoinOperations 'Join Ops');

出力は次のとおりです

Table altered.
また、すでに注釈が存在しているときのエラーを回避するために、IF NOT EXISTS句を使用することもできます。次の文では、JoinOperations注釈が存在しない場合にのみ、その注釈を追加します。その注釈が存在する場合、注釈値は変更されず、エラーは発生しません。
ALTER TABLE Table1
  ANNOTATIONS(ADD IF NOT EXISTS JoinOperations 'Join Ops');
同様に、存在しない注釈を削除するとエラーが発生します:
ALTER TABLE Table1 ANNOTATIONS(DROP Title);

出力は次のとおりです。

ORA-11553: Annotation name 'TITLE' does not exist.
このエラーを回避するために、次のようにIF EXISTS句を使用できます。
ALTER TABLE Table1
  ANNOTATIONS(DROP IF EXISTS Title);

出力は次のとおりです。

Table altered.

関連項目:

句の完全な変更および定義については、『SQL言語リファレンス』のCREATE TABLEおよびALTER TABLE

10.2.5.3 表の列に注釈を付けるDDL文

次のDDL文を使用して、表を作成または変更するときに表の列に注釈を付けることができます。

CREATE TABLE文の使用方法

CREATE TABLE文を使用して列レベルの注釈を追加するには、column_definition句の一部として注釈を指定します。注釈は、末尾のインライン制約の後に指定されます。

次の例では、表作成時に列の注釈を指定します。

CREATE TABLE Table1
  (T NUMBER ANNOTATIONS(Operations 'Sort', Hidden));

CREATE TABLE Table2
  (T NUMBER ANNOTATIONS (Hidden));
 

次の例では、Employee表に表レベルと列レベルの注釈を指定します。

CREATE TABLE Employee (
  Id NUMBER(5) ANNOTATIONS(Identity, Display 'Employee ID', "Group" 'Emp_Info'),
  Ename VARCHAR2(50) ANNOTATIONS(Display 'Employee Name', "Group" 'Emp_Info'),
  Sal NUMBER ANNOTATIONS(Display 'Employee Salary', UI_Hidden)
)
 ANNOTATIONS (Display 'Employee Table');

前の例のEmployee表には、列レベルとオブジェクト・レベルの注釈Displayがあります。この注釈は、列レベルとオブジェクト・レベルで定義されています。新しい注釈は、それに対応するオブジェクトと列のペアが異なっていれば同じ名前で定義できます。たとえば、Employee表にはDisplay名が付いた別の注釈を定義することはできませんが、Sal列に新しい注釈"Group"を定義することはできます。注釈"Group"は予約語であるため、二重引用符で囲む必要があります。

ALTER TABLE文の使用方法

ALTER TABLE文を使用して列レベルの注釈を追加するには、modify_col_properties句の一部として注釈を指定します。注釈は、末尾のインライン制約の後に指定されます。

次の例では、Table1表の列Tに、新しいIdentity注釈を追加します。

ALTER TABLE Table1
  MODIFY T ANNOTATIONS(Identity 'ID');

次の例では、Label注釈を追加して、Identity注釈を削除します。

ALTER TABLE Table1
  MODIFY T ANNOTATIONS(ADD Label, DROP Identity);

関連項目:

句の完全な変更および定義については、『SQL言語リファレンス』のCREATE TABLEおよびALTER TABLE

10.2.5.4 ビューおよびマテリアライズド・ビューに注釈を付けるDDL文

次のDDL文を使用して、ビューおよびマテリアライズド・ビューに注釈を付けることができます。

ビューおよびマテリアライズド・ビューは、ビュー・レベルおよび列レベルで注釈をサポートしています。列レベルの注釈は、列別名定義句の一部として表のビューでのみサポートされています。

CREATE VIEW文の使用方法

次の例では、ビュー・レベルおよび列レベルの注釈を示します。

CREATE OR REPLACE VIEW HighWageEmp  
(
  Id ANNOTATIONS(Identity, Display 'Employee ID', "Group" 'Emp_Info'),
  Ename ANNOTATIONS (Display 'Employee Name',  "Group" 'Emp_Info'),
  Sal  ANNOTATIONS (Display 'Emp Salary')  
)
ANNOTATIONS (Title 'High Wage Employee View')
AS SELECT * FROM EMPLOYEE WHERE Sal > 100000;

CREATE MATERIALIZED VIEW文の使用方法

次の例では、Materialized View文でビュー・レベルの注釈を追加します:

CREATE MATERIALIZED VIEW MView1
  ANNOTATIONS (Title 'Tab1 MV1', ADD Snapshot)
  AS SELECT * FROM Table1;

次の例では、Materialized View文でビュー・レベルおよび列レベルの注釈を追加します:

CREATE MATERIALIZED VIEW MView1(
  T ANNOTATIONS (Hidden)) 
 ANNOTATIONS (Title 'Tab1 MV1', ADD Snapshot)
 AS SELECT * FROM Table1;

ALTER VIEW文の使用方法

注釈をサポートするために、ALTER VIEW文に新しい副句が追加され、ビュー・レベルで注釈を変更できます。ALTER VIEW文でサポートされている他の副句には、ビューの制約の変更、再コンパイルの有効化およびEDITIONABLEプロパティの変更があります。

ビューの列レベルの注釈は変更できません。以前に追加された列レベルの注釈は、ビューを削除し、新しいものを再作成することによってのみ削除できます。

次の例は、Title注釈を削除して、ビュー・レベルでIdentity注釈を追加するALTER VIEW文です。

ALTER VIEW HighWageEmp
  ANNOTATIONS(DROP Title, ADD Identity);

ALTER MATERIALIZED VIEW文の使用方法

ALTER MATERIALIZED VIEW文には、マテリアライズド・ビュー・レベルで注釈をグローバルに変更するために追加された新しい副句があります。列レベルの注釈は、マテリアライズド・ビューを削除して再作成することによってのみ削除できます。

次のALTER MATERIALIZED VIEW文では、MView1からSnapshot注釈を削除します。

ALTER MATERIALIZED VIEW MView1
  ANNOTATIONS(DROP Snapshot);

関連項目:

句の完全な変更および定義については、『SQL言語リファレンス』のCREATE VIEWALTER VIEWCREATE MATERIALIZED VIEWおよびALTER MATERIALIZED VIEW

10.2.5.5 索引に注釈を付けるDDL文

次のDDL文を使用して、索引に注釈を付けることができます。

CREATE INDEX文の使用方法

次に、索引レベルの注釈の作成例を示します。

CREATE TABLE DEPARTMENT(
  DEPT_ID NUMBER,
  UNIT NUMBER);

CREATE INDEX I_DEPT_ID ON DEPARTMENT(DEPT_ID)
  ANNOTATIONS(Display 'Department Index');

CREATE UNIQUE INDEX UI_UNIT ON DEPARTMENT(UNIT)
  ANNOTATIONS(Display 'Department Unique Index');

ALTER INDEX文の使用方法

次に、索引レベルの注釈の変更例を示します。

ALTER INDEX I_DEPT_ID
  ANNOTATIONS(DROP Display, ADD ColumnGroup 'Group1');

関連項目:

句の完全な変更および定義については、『SQL言語リファレンス』のCREATE INDEXおよびALTER INDEX

10.2.5.6 ドメインに注釈を付けるDDL文

次のDDL文を使用して、ドメインに注釈を付けることができます。

ドメインの注釈は、ドメイン・レベルまたは列レベルで指定できます。ドメインで定義された注釈は、そのドメインを参照するオブジェクトに継承されます。注釈は、通常のドメインにのみ使用できます。フレキシブル・ドメインには使用できません。

単一列ドメインのドメイン・レベルの注釈を指定するには、列レベルの注釈とオブジェクト・レベルの注釈を区別するために、カッコ付きの構文(複数列ドメインに使用)が必要です。それ以外の場合、単一列ドメインの注釈は列レベルとみなされます。

CREATE DOMAIN文の使用方法

次の例では、単一列ドメインに列レベルの注釈を指定することで、ドメイン注釈を作成します。

CREATE DOMAIN dept_codes_1 AS NUMBER(3) 
  CONSTRAINT dept_chk_1 CHECK (dept_codes_1 > 99 AND dept_codes_1 != 200) 
  ANNOTATIONS (Title 'Column level annotation');

次の例では、単一列ドメインにドメイン・レベルの注釈を指定します。これには、複数列ドメインに対応するドメイン構文を使用する必要があります(列にカッコを使用します)。

CREATE DOMAIN dept_codes_2 AS (
  code AS NUMBER(3) 
  CONSTRAINT dept_chk_2 CHECK (code > 99 AND code != 200)) 
  ANNOTATIONS (Title 'Domain Annotation');
CREATE DOMAIN HourlyWages AS Number(10) 
  DEFAULT ON NULL 15
  CONSTRAINT MinimalWage CHECK (HourlyWages > = 7 and HourlyWages <=1000) ENABLE
  DISPLAY TO_CHAR(HourlyWages, '$999.99')
  ORDER ( -1*HourlyWages )
  ANNOTATIONS (Title 'Column level annotation');

次の例では、列レベルとドメイン・レベルの注釈がある複数列ドメインを作成します。

CREATE DOMAIN US_City AS (
    name  AS VARCHAR2(50) ANNOTATIONS (Address),
    state AS VARCHAR2(50) ANNOTATIONS (Address),
    zip AS NUMBER ANNOTATIONS (Address)
  )
  CONSTRAINT City_CK CHECK(state in ('CA','AZ','TX') and zip < 100000) 
  DISPLAY name || ', ' || state || ' , ' || TO_CHAR(zip)
  ORDER state || ', ' || TO_CHAR(zip) || ', ' || name
  ANNOTATIONS (Title 'Domain Annotation');

ALTER DOMAIN文の使用方法

オブジェクト・レベルの注釈は、ALTER文で変更できます。ドメインの列レベルの注釈は変更できません。以前に追加された列レベルの注釈は、ドメインを削除し、新しいものを再作成することによってのみ削除できます。

次の例では、dept_codes_2ドメインのドメイン・レベルの注釈を変更します。

ALTER DOMAIN dept_codes_2
  ANNOTATIONS(DROP Title, ADD Name 'Domain');

関連項目:

句の完全な変更および定義については、『SQL言語リファレンス』のCREATE DOMAINおよびALTER DOMAIN

10.2.5.7 ディクショナリ表およびディクショナリ・ビュー

ANNOTATIONS_USAGE$というディクショナリ表には、表やビューなどのスキーマ・オブジェクトでの注釈の使用がすべて含まれます。スキーマ・オブジェクトに新しい注釈名、値あるいはその両方を指定すると、ANNOTATIONS_USAGE$表に新しいエントリが作成されます。同様に、スキーマ・オブジェクトで注釈が削除されると、対応するエントリがANNOTATIONS_USAGE$表から削除されます。

次のディクショナリ・ビューでは、すべてのスキーマ・オブジェクトにわたって注釈とその使用のリストが追跡されます。

  • {DBA|USER|ALL|CDB}_ANNOTATIONS

  • {DBA|USER|ALL|CDB}_ANNOTATIONS_USAGE

  • {DBA|USER|ALL|CDB}_ANNOTATIONS_VALUES

10.2.5.7.1 ディクショナリ・ビューの問合せ

ディクショナリ・ビューに対して問合せを実行し、特定のスキーマ・オブジェクトに使用される注釈のリストを取得できます。

'EMP'表に対して発行された問合せ文の例を次に示します。

'EMP'表の表レベルの注釈を取得する場合:
SELECT * FROM USER_ANNOTATIONS_USAGE
  WHERE Object_Name = 'EMPLOYEE'
   AND Object_Type = 'TABLE'
   AND Column_Name IS NULL;
'EMP'表の列レベルの注釈を取得する場合:
SELECT * FROM USER_ANNOTATIONS_USAGE
  WHERE Object_Name = 'EMPLOYEE'
   AND Object_Type = 'TABLE'
   AND Column_Name IS NOT NULL;
列ごとに単一のJSONコレクションとして'EMP'表の列レベルの注釈を取得する場合:
SELECT  U.Column_Name, JSON_ARRAYAGG(JSON_OBJECT(U.Annotation_Name, U.Annotation_Value))
  FROM USER_ANNOTATIONS_USAGE U
  WHERE Object_Name = 'EMPLOYEE' AND Object_Type = 'TABLE' AND Column_Name IS NOT NULL
  GROUP BY Column_Name;