DOMAIN_CHECK

Syntax

Description of the illustration domain_check_function.gif

Purpose

DOMAIN_CHECK first converts the data type of the arguments in expr to the data type of their corresponding domain columns. It then applies the constraint conditions (not null or check constraint) on domain_name to expr.

If the domain’s constraint is deferred or unvalidated, DOMAIN_CHECK still applies the conditions to expr. If the domain’s constraint is disabled, it is not checked as part of DOMAIN_CHECK.

See Also: Domain Functions

MULTI-COLUMN Domains

When calling DOMAIN_CHECK for multicolumn domains, the number if arguments for expr must match the number of columns in the domain. If there is a mismatch, DOMAIN_CHECK raises an error.

If domain D has n columns, then you should call DOMAIN_CHECK should be called with D+1 arguments, like DOMAIN_CHECK(D, arg1, ..., argn).

If D does not exist or you have no privilege to access D, then an error is raised. If all the checks return true, TRUE is returned. This means that:

Example

The following example creates a domain dgreater with two columns c1 and c2 of type NUMBER and a check constraint that c1 be greater than c2:

CREATE DOMAIN dgreater AS (c1 AS NUMBER, c2 AS NUMBER ) CHECK (c1 > c2);

Then DOMAIN_CHECK (dgreater, 1, 2) returns FALSE because c1 is less than c2 (the check condition fails). DOMAIN_CHECK (dgreater, 2, 1) returns TRUE because because c1 is greater than c2 (the check condition passes).

Flexible Domains

When calling DOMAIN_CHECK for flexible domains, the number of arguments for expr must match the number of domain columns plus discriminant columns. If there is a mismatch DOMAIN_CHECK raises an error.

Checking flexible domain constraints is equivalent to checking constraints of the corresponding subdomain.

You must have the EXECUTE privilege on the flexible domain in order to use DOMAIN_CHECK.

Operations that require EXECUTE privilege on a flexible domain (such as when associating columns with the flexible domain, or during DOMAIN_CHECK with the first argument the flexible domain name) require EXECUTE privilege on the sub-domains. This is because a flexible domain is translated during its creation to a multi-column domain. Therefore the following rules apply:

Examples

Example 1

The following example creates a strict domain of data type CHAR(3 CHAR):

CREATE DOMAIN three_chars AS CHAR(3 CHAR) STRICT;

Calling DOMAIN_CHECK returns true for strings three characters or shorter. For strings four characters or more long it returns false:

SELECT DOMAIN_CHECK (three_chars, 'ab') two_chars,
       DOMAIN_CHECK (three_chars, 'abc') three_chars,
       DOMAIN_CHECK (three_chars, 'abcd') four_chars;

Result:

TWO_CHARS   THREE_CHARS FOUR_CHARS
----------- ----------- -----------
true        true        false

Example 2

The following example creates a domain dgreater with two columns c1 and c2 of type NUMBER and a check constraint that c1 be greater than c2:

CREATE DOMAIN dgreater AS (
  c1 AS NUMBER, c2 AS NUMBER
)
  CHECK (c1 > c2);
SELECT DOMAIN_CHECK (dgreater, 1) one_expr;

ORA-11515: incorrect number of columns in domain association list

The query passes one expression value. This raises an error because there are two columns in the domain.

SELECT DOMAIN_CHECK (dgreater, 1, 2) first_lower,
       DOMAIN_CHECK (dgreater, 2, 1) first_higher,
       DOMAIN_CHECK (dgreater, 'b', 'a') letters;

Result:

FIRST_LOWER FIRST_HIGHER LETTERS
----------- -----------  -------
false       true         false

In the query above :

Example 3

The following example creates the domain DAY_OF_WEEK with no domain constraints. All calls to DOMAIN_CHECK return true because all the input values can be converted to CHAR. It is a non-strict domain, so there is no length check.

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;

Result:

DAY_OF_WEEK_ABBR DOMAIN_COLUMN   NONDOMAIN_COLUMN   DOMAIN_VALUE   NONDOMAIN_VALUE

--------------   -------------- ------------------  -------------- -----------------
MON	       true	     true	         true	    true
tue	       true	     true	         true	    true
fRI	       true	     true	         true	    true

Example 4

The following example creates the domain DAY_OF_WEEK with a constraint to ensure the values are the uppercase day name abbreviations (MON, TUE, etc.). Validating this constraint is deferred until commit, so you can insert invalid values.

Using DOMAIN_CHECK to test the values for the domain column DAY_OF_WEEK_ABBR returns true for the value that conforms to the constraint (MON) and FALSE for those that do not (tue, fRI):

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;

Result:

DAY_OF_WEEK_ABBR  DOMAIN_COLUMN  NONDOMAIN_COLUMN DOMAIN_VALUE NONDOMAIN_VALUE
----------------  -------------  ---------------- ------------ -----------
MON               true	    false	      true	  false
tue               false          false            true         false
fRI               false          false            true         false

Example 5

The following example creates the multicolumn domain currency with two deferred constraints:

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;

The columns amount and currency_code in the table order_items are associated with domain 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');
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;

The query makes four calls to DOMAIN_CHECK:

  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

In the example above:

Example 6

The following statement tries to validate the string “raises an error” against the non-existent domain NOT_A_DOMAIN. This raises an exception:

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.