ПРОВЕРЬТЕ ограничение по дате рождения? - PullRequest
4 голосов
/ 08 декабря 2011

Я создаю свою таблицу сотрудников в Oracle, и для emp_date я хотел бы сделать так, чтобы дата рождения не была давно в прошлом и не могла быть установлена ​​в будущем?

Это слишком сложно для реализации в операторе CREATE TABLE? если это так, то я думаю, что мне придется пропустить это, потому что это та часть, где я должен создать ограничения.

, emp_dob DATE NOT NULL

    CREATE TABLE employee(emp_id NUMBER(4) PRIMARY KEY
, emp_name VARCHAR2(40) NOT NULL
, emp_address VARCHAR2(60) NOT NULL
, emp_tel NUMBER(11) NOT NULL
, CONSTRAINT emp_tel_length CHECK (LENGTH(emp_tel) BETWEEN 9 and 11)
, emp_dob DATE NOT NULL
, CONSTRAINT check_date_of_birth CHECK (emp_dob BETWEEN DATE '1950-01-01' AND sysdate))

Ответы [ 3 ]

9 голосов
/ 08 декабря 2011

Проверка ограничений должна быть детерминированной.То есть конкретная строка всегда должна удовлетворять ограничению, или она всегда должна не удовлетворять ограничению.Но SYSDATE по своей сути недетерминирован, поскольку возвращаемое значение постоянно меняется.Таким образом, вы не можете определить ограничение CHECK, которое вызывает SYSDATE или любую другую пользовательскую функцию.

Если вы попытаетесь сослаться на SYSDATE в определении ограничения, вы получите ошибку

SQL> ed
Wrote file afiedt.buf

  1  create table t(
  2      birth_date date check( birth_date between date '1900-01-01' and
  3                                                sysdate )
  4* )
SQL> /
                                              sysdate )
                                              *
ERROR at line 3:
ORA-02436: date or system variable wrongly specified in CHECK constraint

Вы можете создать ограничение CHECK, в котором минимальная и максимальная дата жестко закодированы, но это не будет особенно практично, поскольку вам придется постоянно отбрасывать и заново создавать ограничение.

SQL> ed
Wrote file afiedt.buf

  1   create table t(
  2       birth_date date check( birth_date between date '1900-01-01' and
  3                                                 date '2011-12-08' )
  4*  )
SQL> /

Table created.

Практическим способом применения такого рода требований является создание триггера для таблицы

CREATE OR REPLACE TRIGGER check_birth_date
  BEFORE INSERT OR UPDATE ON employee
  FOR EACH ROW
BEGIN
  IF( :new.emp_dob < date '1900-01-01' or 
      :new.emp_dob > sysdate )
  THEN
    RAISE_APPLICATION_ERROR( 
      -20001, 
      'EMployee date of birth must be later than Jan 1, 1900 and earlier than today' );
  END IF;
END;
2 голосов
/ 08 декабря 2011

Другим способом было бы создать дату рождения домена со встроенным в домен ограничением. Это позволит вам повторно использовать тот же тип в других определениях таблиц.

CREATE DOMAIN birthdate AS date DEFAULT NULL
    CHECK (value >= '1900-01-01' AND value <= now())
    ;

CREATE TABLE employee
    ( empno INTEGER NOT NULL PRIMARY KEY
    , dob birthdate NOT NULL
    ...
    );
1 голос
/ 20 марта 2014

Как насчет другого обходного пути

Запишите sysdate в столбец и используйте его для проверки. Этот столбец может быть вашим столбцом аудита (например, дата создания)

CREATE TABLE "AB_EMPLOYEE22"
(
   "NAME"     VARCHAR2 ( 20 BYTE ),
   "AGE"      NUMBER,
   "SALARY"   NUMBER,
   "DOB"      DATE,
   "DOJ"      DATE DEFAULT SYSDATE
);

Table Created    

ALTER TABLE "AB_EMPLOYEE22" ADD CONSTRAINT
AGE_CHECK CHECK((ROUND((DOJ-DOB)/365)) = AGE) ENABLE;

Table Altered
...