DOMAIN_CHECK
目的
DOMAIN_CHECK
は、まずexpr
の引数のデータ型を、対応するドメイン列のデータ型に変換します。次に、domain_name
の制約条件(nullまたはチェック制約ではない)をexpr
に適用します。
ドメインの制約が遅延または未検証の場合、DOMAIN_CHECK
でも条件がexpr
に適用されます。ドメインの制約が無効になっている場合は、DOMAIN_CHECK
の一部としてチェックされません。
関連項目:
-
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
はFALSE
を返します。DOMAIN_CHECK
を使用して、特定のドメインの列に挿入できない値をフィルタで除外できます。データ型の変換が成功し、
domain_name
に有効な制約が関連付けられていない場合、DOMAIN_CHECK
はTRUE
を返します。 -
データ型の変換が成功し、
domain_name
に、指定された変換済の値に対してすべて満たされる有効な制約がある場合、DOMAIN_CHECK
はTRUE
を返します。ドメイン制約のいずれかが満たされない場合は、FALSE
を返します。
MULTI-COLUMNドメイン
複数列ドメインに対してDOMAIN_CHECK
をコールする場合、expr
の引数の数がドメイン内の列数と一致する必要があります。一致しない場合、DOMAIN_CHECK
によってエラーが発生します。
ドメインD
にn
列がある場合は、DOMAIN_CHECK(D, arg1, ..., argn)
などのD+1引数を使用してDOMAIN_CHECK
をコールする必要があります。
D
が存在しないか、D
にアクセスする権限がない場合は、エラーが発生します。すべてのチェックがtrueを返した場合、TRUE
が返されます。これは、次のことを意味します:
-
arg1
はD
の列1のデータ型に正常に変換され、arg2
はD
の列2のデータ型に正常に変換され、argn
はD
の列n
のデータ型に正常に変換されます。 -
D
の有効な制約はすべて、D
の列1のデータ型に変換済のarg1
で置換された列1、D
の列2のデータ型に変換済のarg2
で置換された列2、D
の列n
のデータ型に変換済のargn
で置換された列n
で満たされます。
例
次の例では、NUMBER
型の2つの列c1
およびc2
を含むドメインdgreater
と、c1
がc2
より大きいチェック制約を作成します:
CREATE DOMAIN dgreater AS (c1 AS NUMBER, c2 AS NUMBER ) CHECK (c1 > c2);
次に、DOMAIN_CHECK (dgreater, 1, 2)
はFALSE
を返します。これは、c1
がc2
より小さいためです(チェック条件が失敗します)。c1
がc2
より大きい(チェック条件が合格する)ため、DOMAIN_CHECK (dgreater, 2, 1)
はTRUE
を返します。
フレキシブル・ドメイン
フレキシブル・ドメインに対してDOMAIN_CHECK
をコールする場合、expr
の引数の数は、ドメイン列と判別式の数と一致する必要があります。一致しない場合、DOMAIN_CHECK
によってエラーが発生します。
フレキシブル・ドメイン制約の確認は、対応するサブドメインの制約の確認と同じです。
DOMAIN_CHECK
を使用するには、フレキシブル・ドメインに対するEXECUTE
権限が必要です。
フレキシブル・ドメインに対するEXECUTE
権限が必要な操作(列をフレキシブル・ドメインに関連付ける場合や、最初の引数のフレキシブル・ドメイン名にDOMAIN_CHECK
を行う場合など)には、サブドメインに対するEXECUTE
権限が必要です。これは、フレキシブル・ドメインが作成中に複数列ドメインに変換されるためです。したがって、次のルールが適用されます:
-
列をフレックス・ドメインに関連付けることは、対応する複数列ドメインに関連付けることと同じです。
-
フレキシブル・ドメイン制約の確認は、対応する複数列ドメインの制約の確認と同じです。
-
フレキシブル・ドメイン表示および順序プロパティの評価は、対応する複数列ドメインのプロパティの評価と同等です。
例
例1
次の例では、データ型CHAR(3 CHAR)
の厳密なドメインを作成します:
CREATE DOMAIN three_chars AS CHAR(3 CHAR) STRICT;
DOMAIN_CHECK
をコールすると、3文字以下の文字列に対してtrueが返されます。4文字以上の長さの文字列の場合は、falseを返します:
SELECT DOMAIN_CHECK (three_chars, 'ab') two_chars, DOMAIN_CHECK (three_chars, 'abc') three_chars, DOMAIN_CHECK (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 (dgreater, 1) one_expr; ORA-11515: incorrect number of columns in domain association list
2番目の問合せでは次のようになります:
-
first_lower
はドメイン制約に失敗するため、FALSE
です -
first_higher
はドメイン制約に合格するため、TRUE
です -
値は数値に変換できないため、
letters
はFALSE
です
SELECT DOMAIN_CHECK (dgreater, 1, 2) first_lower, DOMAIN_CHECK (dgreater, 2, 1) first_higher, DOMAIN_CHECK (dgreater, 'b', 'a') letters; FIRST_LOWER FIRST_HIGHER LETTERS ----------- ----------- ----------- FALSE TRUE FALSE
例3
次の例では、ドメイン制約のないドメインDAY_OF_WEEK
を作成します。すべての入力値をCHAR
に変換できるため、DOMAIN_CHECK
へのすべてのコールは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(day_of_week, day_of_week_abbr) domain_column, DOMAIN_CHECK(day_of_week, calendar_date) nondomain_column, DOMAIN_CHECK(day_of_week, CAST('MON' AS day_of_week)) domain_value, DOMAIN_CHECK(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
を使用してドメイン列DAY_OF_WEEK_ABBR
の値をテストすると、制約(MON
)に準拠する値に対してTRUE
が返され、準拠しない値(tue
、fRI
)に対してFALSE
が返されます:
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(day_of_week, day_of_week_abbr) domain_column, DOMAIN_CHECK(day_of_week, calendar_date) nondomain_column, DOMAIN_CHECK(day_of_week, CAST('MON' AS day_of_week)) domain_value, DOMAIN_CHECK(day_of_week, 'mon') nondomain_value FROM calendar_dates; DAY DOMAIN_COLUMN NONDOMAIN_COLUMN DOMAIN_VALUE NONDOMAIN_VALUE --- ------------- ---------------- ------------ ----------- MON TRUE FALSE TRUE FALSE tue FALSE FALSE TRUE FALSE fRI FALSE FALSE TRUE FALSE
例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
を4回コールします:
SELECT order_id, product_id, amount, currency_code, DOMAIN_CHECK(currency, order_id, product_id) order_product, DOMAIN_CHECK(currency, amount, currency_code) amount_currency, DOMAIN_CHECK(currency, currency_code, amount) currency_amount, DOMAIN_CHECK(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 FALSE TRUE FALSE TRUE 2 2 1234.56 GBP FALSE TRUE FALSE TRUE 3 3 -999999 JPY FALSE FALSE FALSE TRUE 4 4 3141592 XXX FALSE FALSE FALSE FALSE 5 5 2718281 123 FALSE FALSE FALSE FALSE
前述の例では次のようになります:
-
PRODUCT_ID
の値がsupported_currencies_c
制約に準拠していないため、ORDER_PRODUCT
は、すべての行に対してFALSE
です。 -
AMOUNT_CURRENCY
は、制約(AMOUNT = -999999
およびCURRENCY_CODE = "XXX"
および"123"
)に違反する値を含む行に対してFALSE
です。有効な値の場合はTRUE
です。 -
CURRENCY_AMOUNT
は、すべての行に対してFALSE
です。これは、最初の4行で最初の引数の値CURRENCY_CODE
がすべて文字であるためです。これらをドメインの最初の列の型(NUMBER
)に変換できないため、型エラーになります。5番目の行では、金額(2718281
)はsupported_currencies_c
制約に準拠していません。 -
ORDER_CURRENCY
は、制約(CURRENCY_CODE = "XXX"
および"123"
)に違反する値を含む行に対してFALSE
です。有効な値の場合はTRUE
です。
例6
次の文は、存在しないドメインNOT_A_DOMAIN
に対して文字列"raises an error"を検証しようとします。これにより、例外が発生します:
SELECT DOMAIN_CHECK(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.