DOMAIN_CHECK_TYPE
目的
DOMAIN_CHECK_TYPEを使用すると、ドメイン制約をチェックせずに、値式をドメイン列のデータ型に変換できます。制約をチェックする場合は、DOMAIN_CHECKを使用する必要があります。
DOMAIN_CHECK_TYPEは、DOMAIN_CHECKと同じ引数を取り、引数のデータ型が対応するドメイン列のデータ型と一致する場合はTRUEを返します。データ型が一致しない場合、FALSEが返されます。
関連項目:
-
domain_nameは識別子である必要があり、domain_owner.domain_nameを使用して指定できます。domain_ownerなしで指定すると、最初に現在のユーザーに解決され、次にパブリック・シノニムとして解決されます。名前を解決できない場合は、エラーが発生します。 -
domain_nameが存在しないドメインまたはEXECUTE権限を持たないドメインを参照している場合、DOMAIN_CHECKはエラーを生成します。 -
ドメイン列のデータ型が
STRICTの場合、値はドメイン列のデータ型に変換されます。たとえば、ドメイン列のデータ型がVARCHAR2(100) STRICTの場合、値はVARCHAR2(100)に変換されます。変換によって入力が最大長に自動的に切り捨てられることはありません。値が一部の行で'abc'と評価され、ドメインのデータ型がCHAR(2 CHAR)の場合、'ab'を返すかわりに変換は失敗します。ドメイン列のデータ型が
STRICTでない場合、値は、長さ、スケールおよび精度に関してドメイン列のデータ型の最も許容できる形に変換されます。たとえば、入力値がVARCHAR2(30)の場合、ドメイン長より短いため、VARCHAR2(100)に変換されます。入力値がVARCHAR2(200)の場合は、ドメイン長よりも大きいため、VARCHAR2(200)のままになります。 -
データ型の変換に失敗すると、エラーがマスクされ、
DOMAIN_CHECK_TYPEはFALSEを返します。DOMAIN_CHECK_TYPEを使用して、特定のドメインの列に挿入できない値をフィルタで除外できます。
MULTI-COLUMNドメイン
複数列ドメインに対してDOMAIN_CHECK_TYPEをコールする場合、exprの引数の数がドメイン内の列数と一致する必要があります。一致しない場合、DOMAIN_CHECK_TYPEによってエラーが発生します。
フレキシブル・ドメイン
フレキシブル・ドメインに対してDOMAIN_CHECK_TYPEをコールする場合、exprの引数の数は、ドメイン列と判別式の数と一致する必要があります。一致しない場合、DOMAIN_CHECK_TYPEによってエラーが発生します。
例
例1
次の例では、データ型CHAR(3 CHAR)の厳密なドメインを作成します:
CREATE DOMAIN three_chars AS CHAR(3 CHAR) STRICT;
DOMAIN_CHECK_TYPEをコールすると、3文字以下の文字列に対してtrueが返されます。4文字以上の長さの文字列の場合は、falseを返します:
SELECT DOMAIN_CHECK_TYPE (three_chars, 'ab') two_chars,
DOMAIN_CHECK_TYPE (three_chars, 'abc') three_chars,
DOMAIN_CHECK_TYPE (three_chars, 'abcd') four_chars;
TWO_CHARS THREE_CHARS FOUR_CHARS
----------- ----------- -----------
TRUE TRUE FALSE
例2
次の例では、NUMBER型の2つの列c1およびc2を含むドメインdgreaterと、c1がc2より大きいチェック制約を作成します:
CREATE DOMAIN dgreater AS ( c1 AS NUMBER, c2 AS NUMBER ) CHECK (c1 > c2);
最初の問合せは1つの式値を渡します。ドメインに2つの列があるため、エラーが発生します。
SELECT DOMAIN_CHECK_TYPE (dgreater, 1) one_expr; ORA-11515: incorrect number of columns in domain association list
-
値が数値であるため、
first_lowerとfirst_higherは両方ともTRUEです。ドメイン制約はチェックされません。 -
値が数値に変換できないため、
lettersはFALSEです。
SELECT DOMAIN_CHECK_TYPE (dgreater, 1, 2) first_lower,
DOMAIN_CHECK_TYPE (dgreater, 2, 1) first_higher,
DOMAIN_CHECK_TYPE (dgreater, 'b', 'a') letters;
FIRST_LOWER FIRST_HIGHER LETTERS
----------- ----------- -----------
TRUE TRUE FALSE例3
次の例では、ドメイン制約のないドメインDAY_OF_WEEKを作成します。すべての入力値をCHARに変換できるため、DOMAIN_CHECK_TYPEへのすべてのコールはtrueを返します。これは厳密でないドメインであるため、長さのチェックはありません。
CREATE DOMAIN day_of_week AS CHAR(3 CHAR);
CREATE TABLE calendar_dates (
calendar_date DATE,
day_of_week_abbr day_of_week
);
INSERT INTO calendar_dates
VALUES(DATE'2023-05-01', 'MON'),
(DATE'2023-05-02', 'tue'),
(DATE'2023-05-05', 'fRI');
SELECT day_of_week_abbr,
DOMAIN_CHECK_TYPE(day_of_week, day_of_week_abbr) domain_column,
DOMAIN_CHECK_TYPE(day_of_week, calendar_date) nondomain_column,
DOMAIN_CHECK_TYPE(day_of_week, CAST('MON' AS day_of_week)) domain_value,
DOMAIN_CHECK_TYPE(day_of_week, 'mon') nondomain_value
FROM calendar_dates;
DAY DOMAIN_COLUMN NONDOMAIN_COLUMN DOMAIN_VALUE NONDOMAIN_VALUE
--- --------------- ------------------ -------------- -----------------
MON TRUE TRUE TRUE TRUE
TUE TRUE TRUE TRUE TRUE
FRI TRUE TRUE TRUE TRUE
mon TRUE TRUE TRUE TRUE
MON TRUE TRUE TRUE TRUE 例4
次の例では、値が大文字の曜日名の略語(MON、TUEなど)になるように、制約付きのドメインDAY_OF_WEEKを作成します。
この制約の検証はコミットまで遅延されるため、無効な値を挿入できます。
DOMAIN_CHECK_TYPEを使用すると、すべての値が型チェックに合格するため、すべての値に対してTRUEが返されます:
CREATE DOMAIN day_of_week AS CHAR(3 CHAR)
CONSTRAINT CHECK(day_of_week IN ('MON','TUE','WED','THU','FRI','SAT','SUN'))
INITIALLY DEFERRED;
CREATE TABLE calendar_dates (
calendar_date DATE,
day_of_week_abbr day_of_week
);
INSERT INTO calendar_dates
VALUES(DATE'2023-05-01', 'MON'),
(DATE'2023-05-02', 'tue'),
(DATE'2023-05-05', 'fRI');
SELECT day_of_week_abbr,
DOMAIN_CHECK_TYPE(day_of_week, day_of_week_abbr) domain_column,
DOMAIN_CHECK_TYPE(day_of_week, calendar_date) nondomain_column,
DOMAIN_CHECK_TYPE(day_of_week, CAST('MON' AS day_of_week)) domain_value,
DOMAIN_CHECK_TYPE(day_of_week, 'mon') nondomain_value
FROM calendar_dates;
DAY DOMAIN_COLUMN NONDOMAIN_COLUMN DOMAIN_VALUE NONDOMAIN_VALUE
--- ------------- ---------------- ------------ -----------
MON TRUE TRUE TRUE TRUE
tue FALSE TRUE TRUE TRUE
fRI FALSE TRUE TRUE TRUE例5
次の例では、2つの遅延制約を持つ複数列のドメイン通貨を作成します:
CREATE DOMAIN currency AS ( amount AS NUMBER(10, 2) currency_code AS CHAR(3 CHAR) ) CONSTRAINT supported_currencies_c CHECK ( currency_code IN ( 'USD', 'GBP', 'EUR', 'JPY' ) ) DEFERRABLE INITIALLY DEFERRED CONSTRAINT non_negative_amounts_c CHECK ( amount >= 0 ) DEFERRABLE INITIALLY DEFERRED;
表ORDER_ITEMSの列AMOUNTおよびCURRENCY_CODEは、ドメインcurrencyに関連付けられています:
CREATE TABLE order_items (
order_id INTEGER,
product_id INTEGER,
amount NUMBER(10, 2),
currency_code CHAR(3 CHAR),
DOMAIN currency(amount, currency_code)
);
INSERT INTO order_items
VALUES (1, 1, 9.99, 'USD'),
(2, 2, 1234.56, 'GBP'),
(3, 3, -999999, 'JPY'),
(4, 4, 3141592, 'XXX') ,
(5, 5, 2718281, '123');この問合せでは、DOMAIN_CHECK_TYPEを4回コールします:
SELECT order_id,
product_id,
amount,
currency_code,
DOMAIN_CHECK_TYPE(currency, order_id, product_id) order_product,
DOMAIN_CHECK_TYPE(currency, amount, currency_code) amount_currency,
DOMAIN_CHECK_TYPE(currency, currency_code, amount) currency_amount,
DOMAIN_CHECK_TYPE(currency, order_id, currency_code) order_currency
FROM order_items;
ORDER_ID PRODUCT_ID AMOUNT CUR ORDER_PRODUCT AMOUNT_CURRENCY CURRENCY_AMOUNT ORDER_CURRENCY
---------- ---------- ---------- --- ------------- --------------- --------------- -----------
1 1 9.99 USD TRUE TRUE FALSE TRUE
2 2 1234.56 GBP TRUE TRUE FALSE TRUE
3 3 -999999 JPY TRUE TRUE FALSE TRUE
4 4 3141592 XXX TRUE TRUE FALSE TRUE
5 5 2718281 123 TRUE TRUE TRUE TRUE前述の例では次のようになります:
-
ORDER_IDおよびPRODUCT_IDの値はドメイン内の対応する列型(NUMBERおよびCHAR)に変換できるため、すべての行に対してORDER_PRODUCTはTRUEです。 -
表の列がドメイン列と一致するため、すべての行に対して
AMOUNT_CURRENCYはTRUEです。 -
最初の引数
CURRENCY_CODEの値はすべての文字であるため、最初の4行に対してCURRENCY_AMOUNTはFALSEです。これらをドメインの最初の列の型(NUMBER)に変換できないため、型エラーになります。5行目はTRUEです。これは、金額(2718281)をCHARに変換できるためです。 -
ORDER_IDおよびCURRENCY_CODEの型は対応するドメイン列型(NUMBERおよびCHAR)と一致するため、すべての行に対してORDER_CURRENCYはTRUEです。
例6
次の文は、存在しないドメインNOT_A_DOMAINに対して文字列"raises an error"を検証しようとします。これにより、例外が発生します:
SELECT DOMAIN_CHECK_TYPE(not_a_domain, 'raises an error'); ORA-11504: The domain specified does not exist or the user does not have privileges on the domain for the operation.
