Определение контролируемого значения столбца
Спецификация

См. спецификацию пункта «Создание таблицы».

Синтаксические правила
  1. Конструкция < контролируемое значение столбца > задает условие, которому должно удовлетворять значение столбца при операции добавления (модификации) записи. Если < контролируемое значение столбца > возвращает значение true, то значение столбца считается корректным, в противном случае – недопустимым.

  2. < Логическое выражение > не должно содержать ссылок на другие столбцы данной таблицы, кроме него самого.

    Проверка кода города в телефонных номерах
    create or replace table test (col1 char(15) check (substr(col1,1,3)='473'));
    insert into test(col1) values ('473-2-711-711');
    insert into test(col1) values ('495-274-453-776'); //недопустимая запись.
    insert into test(col1) values ('473-2-654-300');
    select * from test
    | 473-2-711-711|
    | 473-2-654-300|
  3. Использование столбцов с атрибутом AUTOROWID в < логическом выражении > запрещено.

  4. Использование предиката [NOT] CONTAINS в < логическом выражении > конструкции запрещено (см. документ «Полнотекстовый поиск в базе данных», пункт «Предикат полнотекстового поиска»).

  5. Разрешено использование значений SYSDATE, NOW, LOCALTIME, LOCALTIMESTAMP, CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP в < контролируемом значении столбца >. Однако при этом в БД могут оказаться записи, которые удовлетворяли < контролируемому значению столбца > в момент выполнения операции INSERT/ UPDATE, но со временем перестали удовлетворять этому ограничению, т.к. текущее значение этих значений стало другим.

    select to_localtime(sysdate);
    create or replace table test(i int, d date default localtimestamp on update current_time check (d <  localtimestamp + to_date('01','SS')));
    
    insert into test(i) values(1);
    select d from test;
    update test set i=2;
    select d from test;
    
    ! запись не удовлетворяет условию CHECK
    insert into test(i, d) values(2,localtimestamp + to_date('02','SS'));
    Результат работы примера:
    |05.03.2012:16:25:48.47|
    
     D
     -
    |05.03.2012:16:25:48.52|
    
     D
     -
    |00.00.0000:16:25:48.52|
    
    INL : состояние выполнения : 914
    Запись не удовлетворяет условию CHECK
  6. < Логическое выражение > не должно содержать подзапросов, агрегатных функций, конструкций CASE и CAST, функций SECURITY, INDEXTIME, LEAD, LAG, GETTEXTPOS.

    Примеры.
    а)
    create or replace table test (col1 int check (col1 between 100 and 200));
    
    insert into test (col1)  values (100);
    insert into test (col1)  values (250); /* ошибка  */
    
    б)
    create or replace table test (col1 int check (col1 not in (10,20,30)));
    
    insert into test (col1)  values (200);
    insert into test (col1)  values (20); /* ошибка  */
    
    в)
    create or replace table test (col1 char(20) check (col1 not like 'В%'));
    
    insert into test (col1)  values ('Воронеж'); /* ошибка  */
    insert into test (col1)  values ('Москва');
    insert into test (col1)  values ('Урюпинск');
    
    г)
    create or replace table test (col1 char(20) check (col1 similar to 'B_W'));
    
    insert into test (col1)  values ('BMW');
    insert into test (col1)  values ('MERCEDES'); /* ошибка  */
    insert into test (col1)  values ('LADA'); /* ошибка  */
    insert into test (col1)  values ('B9W');
    д)
    create or replace table test (col1 real check (col1 is not null));
    
    insert into test (col1)  values (56.008);
    insert into test; /* ошибка  */
  7. Каждый столбец может иметь произвольное число < контролируемых значений столбца >, но суммарная длина всех оттранслированных < контролируемых значений столбца > не должна превышать 4 Кбайт.

    create or replace table tst_check(i int check (i >0) check (i<  >1) check ((i<  >18) and (i<  >20)), c char(10) default 'Сумма');
    
    insert into tst_check(i) values(2);
    insert into tst_check(i) values(1); /* ошибка */
    insert into tst_check(i) values(-5); /* ошибка */
    insert into tst_check(i) values(18); /* ошибка */
    insert into tst_check(i) values(10);
    select c, i from tst_check;
    |Сумма|    2|
    |Сумма|   10|
  8. Конструкция может задаваться в любом месте среди атрибутов столбца.

    create or replace table tst_check(i int default 0 check (i >0) check (i<  >1) check ((i<  >18) and (i<  >20)), c char(10) default 'Сумма');
    
    create or replace table tst_check(i int check (i >0) check (i<  >1) default 0 check ((i<  >18) and (i<  >20)), c char(10) default 'Сумма');
    
    Несколько CHECK можно заменить одним
    create or replace table tst_check(i int check ((i >0) and (i<  >1) and ((i<  >18) and (i<  >20))), c char(10) default 'Сумма');
    
    create or replace table tst_check(i int check (col_check=1));
    
    create or replace procedure col_check (in i int) result int for debug
    code
      if i >1 then 
        return 1; 
      else 
        return 0; 
      endif
    end;
    call col_check(-4);
    
    insert into tst_check(i) values(default);
    insert into tst_check(i) values(2);
    insert into tst_check(i) values(-3);
    select i from tst_check;
    delete from tst_check;
  9. < Контролируемое значение столбца > не должно содержать ссылок на другие столбцы данной таблицы, кроме него самого.

  10. < Логическое выражение > может содержать ссылки только на столбцы данной таблицы, которые уже определены в < спецификации столбцов таблицы >.

    create table t (i int, j int, check (i >j));
    
    Дата поставки товара должна быть не позже, чем через месяц после его изготовления
    create or replace table pstv (crt date default sysdate, sale date, check(divtime(16,to_date(crt,'DD:MM:YYYY'), to_date(sale,'DD:MM:YYYY'))< 30));
    
    insert into pstv (sale) values (to_date('25:02:2018','DD:MM:YYYY'));
    insert into pstv (sale) values (to_date('10:03:2018','DD:MM:YYYY')); /* ошибка */
    select * from pstv;
    |02.02.2018:08:36:17| 25.02.2018:00:00:00|
    
    Следующие два оператора эквивалентны:
    create table t (i int, j int, check ((i >j) and (i< j+10)));
    create table t (i int, j int, check (i >j), check (i< j+10));
  11. < Контролируемые значения записи > должно задаваться через запятую либо после определения всех столбцов таблицы, либо после определения задействованных в < логическом выражении > столбцов.

    Варианты:
    В конце списка определяемых столбцов
    create or replace table tst_check (i int, c char(10), d decimal, check((i+d)< to_number(c)));
    
    Внутри списка определяемых столбцов
    create or replace table tst_check (i int, d decimal, check((i+d)< 100.0), c char(10));
    
    create or replace table tst_check(i int default 0 check (i >0) check (i<  >1) check ((i<  >18) and (i<  >20)), c char(10) default 'Сумма');
    
    create or replace table tst_check(i int check (i >0) check (i<  >1) default 0 check ((i<  >18) and (i<  >20)), c char(10) default 'Сумма');
  12. Несколько < логических условий > можно заменять одним < логическим условием >.

    create or replace table tst_check(i int check ((i >0) and (i<  >1) and ((i<  >18) and (i<  >20))), c char(10) default 'Сумма');
Примеры
  1. create or replace table test (col1 int check ((col1 between 10 and 30) and (col1<  >15) and (col1 >12)));
    
    insert into test (col1) values(11); / ошибка
    insert into test (col1) values(15); / ошибка
    insert into test (col1) values(37); / ошибка
    insert into test (col1) values(20);
  2. create or replace table test (col1 int check ((col1 between 10 and 30) and (col1<  >15) and (col1 >12)),
    col2 char(20) check (col2 not like 'А%') check (col2 not like 'Б%') check (col2 not like 'В%'),
    col3 real check (col3*0.5+45.90 >0));
    
    insert into test (col1, col2, col3) values (25, 'Москва', 56.89);
    insert into test (col1, col2, col3) values (25, 'Воронеж', 45.99); // ошибка
    insert into test (col1, col2, col3) values (25, 'Урюпинск', -112.7); // ошибка
  3. Следующие два оператора делают одно и то же:

    create table t (i int check ((i >0) and (i< 10)));
    create table t (i int check (i >0) check (i< 10));
  4. create or replace table test (col1 int check (col1 between 100 and 200));
    
    insert into test (col1)  values (100);
    insert into test (col1)  values (250); /* ошибка */
  5. create or replace table test (col1 int check (col1 not in (10,20,30)));
    
    insert into test (col1)  values (200);
    insert into test (col1)  values (20); /* ошибка */
  6. create or replace table test (col1 char(20) check (col1 not like 'В%'));
    
    insert into test (col1)  values ('Воронеж'); /* ошибка */
    insert into test (col1)  values ('Москва');
    insert into test (col1)  values ('Урюпинск');
  7. create or replace table test (col1 char(20) check (col1 similar to 'B_W'));
    
    insert into test (col1)  values ('BMW');
    insert into test (col1)  values ('MERCEDES'); /* ошибка */
    insert into test (col1)  values ('LADA'); /* ошибка */
    insert into test (col1)  values ('B9W');
  8. create or replace table test (col1 real check (col1 is not null));
    
    insert into test (col1)  values (56.008);
    insert into test; /* ошибка */
Общие правила
  1. Конструкция < контролируемые значения записи > задает условие, которому должно удовлетворять значение столбца (столбцов) при операции добавления/изменения записи. Если < контролируемые значения записи > возвращает значение true, то запись считается корректной, в противном случае – недопустимой.

  2. < Контролируемые значения записи > проверяются в том же порядке, в каком они создавались.

  3. Таблица может иметь произвольное число < контролируемых значений записи >, но суммарная длина всех оттранслированных < контролируемых значений записи > не должна превышать 4 Кбайт.

Примеры
  1. create or replace table test
    (col1 int check ((col1 between 10 and 30) and (col1<  >15) and (col1 >12)));
    
    insert into test (col1) values(11); /* ошибка */
    insert into test (col1) values(15); /* ошибка */
    insert into test (col1) values(37); /* ошибка */
    insert into test (col1) values(20);
  2. create or replace table test (col1 int check ((col1 between 10 and 30) and (col1<  >15) and (col1 >12)), col2 char(20) check (col2 not like 'А%') check (col2 not like 'Б%') check (col2 not like 'В%'), col3 real check (col3*0.5+45.90 >0));
    
    insert into test (col1, col2, col3) values (25, 'Москва', 56.89);
    insert into test (col1, col2, col3) values (25, 'Воронеж', 45.99); /* ошибка */
    insert into test (col1, col2, col3) values (25, 'Урюпинск', -112.7); /* ошибка */
  3. Следующие два оператора делают одно и то же:

    create table t (i int check ((i >0) and (i< 10)));
    create table t (i int check (i >0) check (i< 10));