Тип столбца Oracle - только год - не больше текущего года [дубликат]

Random ra = new Random();
int r, g, b;
r=ra.nextInt(255);
g=ra.nextInt(255);
b=ra.nextInt(255);
Color color = new Color(r,g,b);
String hex = Integer.toHexString(color.getRGB() & 0xffffff);
if (hex.length() < 6) {
    hex = "0" + hex;
}
hex = "#" + hex;
6
задан Hubert Kario 5 February 2012 в 21:02
поделиться

6 ответов

К сожалению, контрольное ограничение не может ссылаться на функцию типа SYSDATE. Вам понадобится создать триггер, который проверял эти значения, когда происходит DML, т. Е.

CREATE OR REPLACE TRIGGER trg_check_dates
  BEFORE INSERT OR UPDATE ON table1
  FOR EACH ROW
BEGIN
  IF( :new.CloseDate <= SYSDATE )
  THEN
    RAISE_APPLICATION_ERROR( -20001, 
          'Invalid CloseDate: CloseDate must be greater than the current date - value = ' || 
          to_char( :new.CloseDate, 'YYYY-MM-DD HH24:MI:SS' ) );
  END IF;
  IF( :new.CloseDate > add_months(SYSDATE,12) )
  THEN
    RAISE_APPLICATION_ERROR( -20002, 
         'Invalid CloseDate: CloseDate must be within the next year - value = ' || 
         to_char( :new.CloseDate, 'YYYY-MM-DD HH24:MI:SS' ) );
  END IF;
  IF( :new.StartDate <= add_months(:new.CloseDate,24) )
  THEN
    RAISE_APPLICATION_ERROR( -20002, 
          'Invalid StartDate: StartDate must be within 24 months of the CloseDate - StartDate = ' || 
          to_char( :new.StartDate, 'YYYY-MM-DD HH24:MI:SS' ) ||
          ' CloseDate = ' || to_char( :new.CloseDate , 'YYYY-MM-DD HH24:MI:SS' ) );
  END IF;
END;
13
ответ дан Justin Cave 20 August 2018 в 07:45
поделиться

Вы не можете использовать SYSDATE в контрольном ограничении. Согласно документации

Условия проверочных ограничений не могут содержать следующие конструкции:

  • Подзапросы и выражения скалярного подзапроса
  • Вызов функций, которые не являются детерминированными (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER и USERENV)
  • Вызов пользовательских функций
  • Выделение столбцов REF ( например, с помощью функции DEREF)
  • Вложенные столбцы или атрибуты таблицы
  • Псевдоколонны CURRVAL, NEXTVAL, LEVEL или ROWNUM
  • Константы даты, которые не полностью

Для 10g Release 2 (10.2) см. ограничение , и для 11g Release 2 (11.2) см. ограничение .

Помните, что ограничение целостности - это утверждение о данных таблицы, которое всегда истинно.

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

13
ответ дан DavidRR 20 August 2018 в 07:45
поделиться

Я не рекомендую использовать триггеры в качестве ограничения и увеличивать исключения. Вместо этого вы можете использовать столбец для хранения SYSDATE в качестве даты регистрации (если у вас уже есть его, то вы можете его использовать), а затем ваше ограничение сравнивает этот столбец вместо SYSDATE

 ALTER TABLE Table1
 ADD (REGISTER_DATE DATE);

 CREATE OR REPLACE TRIGGER trg_check_dates
   BEFORE INSERT OR UPDATE ON table1
   FOR EACH ROW
 BEGIN
   :new.REGISTER_DATE := SYSDATE;
 END;

 ALTER TABLE Table1
 ADD (CONSTRAINT GT_Table1_CloseDate
 CHECK (CloseDate > REGISTER_DATE),
 CONSTRAINT LT_Table1_CloseDate
 CHECK (CloseDate <= REGISTER_DATE + 365)),
 CONSTRAINT GT_Table1_StartDate
 CHECK (StartDate > (CloseDate + (REGISTER_DATE + 730))));
0
ответ дан hmmftg 20 August 2018 в 07:45
поделиться

Каждый раз, когда запись обновляется, SYSDATE будет иметь другое значение. Поэтому ограничение будет проверять по-разному каждый раз. По этой причине Oracle не разрешает sysdate в ограничении.

Возможно, вы сможете решить свою проблему с помощью триггера, который проверяет, действительно ли CloseDate изменил и вызвал исключение, когда новое значение не находится в пределах диапазона.

И: Что такое (StartDate > (CloseDate + (SYSDATE + 730))))? Вы не можете добавлять даты.

И: StartDate должно быть после CloseDate? Это не странно?

4
ответ дан Kirk Woll 20 August 2018 в 07:45
поделиться

Записать 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
4
ответ дан SriniV 20 August 2018 в 07:45
поделиться

Вы можете добиться этого, когда вы немного обманете:

CREATE OR REPLACE FUNCTION SYSDATE_DETERMINISTIC RETURN DATE DETERMINISTIC IS
BEGIN
    RETURN SYSDATE;
END SYSDATE_DETERMINISTIC;
/

CREATE TABLE Table1 (
   s_date DATE, 
   C_DATE DATE GENERATED ALWAYS AS ( SYSDATE_DETERMINISTIC() ) 
);

ALTER TABLE Table1 ADD CONSTRAINT s_check CHECK ( s_date < C_DATE );

Конечно, функция SYSDATE_DETERMINISTIC не детерминирована, но Oracle позволяет объявить это в любом случае.

Возможно, в будущих выпусках Oracle станет более умным и больше не позволит такие трюки.

1
ответ дан Wernfried Domscheit 20 August 2018 в 07:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: