создать триггер pl sql

avatar
raju
8 апреля 2018 в 05:22
88
2
1

Я пытаюсь написать триггер для before insert, чтобы проверить дату обращения. Дата обращения должна быть между 5 годами до и 7 годами после текущей даты.

Например, в 2018 году дата обращения должна быть с 2013 по 2025 год. Если дата выходит за пределы допустимого диапазона, триггер должен перестать вставлять данные.

CREATE OR REPLACE TRIGGER ch
BEFORE INSERT 
on CASE
FOR EACH ROW 
DECLARE

    CASN number;
BEGIN
    SELECT COUNT(*) 
    INTO CASN
    FROM CASE
    WHERE :new.STARTDATE > SYSDATE;
    IF (CASN > 0) THEN
        RAISE_APPLICATION_ERROR(-20000,'Start DATE CANNOT Be GREATER than today's 
date');
END IF; 
END;

Здесь STARTDATE — столбец CASE таблицы

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

Как мне добавить указанный интервал к sysdate, чтобы он работал для указанного выше условия?

Источник

Ответы (2)

avatar
Kaushik Nayak
8 апреля 2018 в 05:46
3

Логика, которую вы используете в своем Trigger, совершенно неверна. Вам не нужно получать количество из таблицы, используя :NEW.STARTDATE. Это то, что вы ищете.

CREATE OR replace TRIGGER ch
  BEFORE INSERT ON cases
  FOR EACH ROW
BEGIN
    IF ( :NEW.casedate < SYSDATE - INTERVAL '5' year
         OR :NEW.casedate > SYSDATE + INTERVAL '7' year ) THEN
      RAISE_APPLICATION_ERROR(-20000,
'CASE DATE should be in range: current date - 5 years and current date + 7 years')
;
END IF;
END;

/  

EDIT: я не добавил TRUNC в даты, потому что я не уверен, хотите ли вы также учитывать компонент времени при рассмотрении диапазона дат. Если вы согласны только с учетом дней, вы можете использовать TRUNC(SYSDATE) вместо простого SYSDATE. Измените его в соответствии с потребностями вашего бизнеса.

Еще один вариант — использовать ограничение CHECK. Хотя Oracle не позволяет вам иметь используйте SYSDATE в определении ограничения проверки, вы можете создать другой столбец (или повторно использовать существующий), который по умолчанию равен SYSDATE, и применить к нему ограничение проверки.

ALTER TABLE CASES ADD ( CURR_DATE DATE DEFAULT SYSDATE );

ALTER TABLE CASES ADD CONSTRAINT
RANGE_CHECK CHECK( casedate > CURR_DATE - INTERVAL '5' YEAR
                   AND casedate < CURR_DATE + INTERVAL '7' YEAR) ENABLE;
APC
8 апреля 2018 в 07:41
0

Обычно таблицы имеют столбец метаданных, например DATE_CREATED, для отслеживания истории записи. Мы могли бы использовать такой столбец в проверочном ограничении. Кроме того, может быть хорошей идеей обрезать даты (конечно, sysdate в нижней границе), чтобы элемент времени не ошибся с действительной датой.

Kaushik Nayak
8 апреля 2018 в 08:50
1

@APC: Спасибо. Я добавил примечание в ответ.

avatar
Anuj Arora
8 апреля 2018 в 05:41
-1

Арифметика даты. Oracle Database позволяет выполнять арифметические операции с датами и отметками времени несколькими способами:

Добавление числового значения к дате или вычитание его из даты, как в SYSDATE + 7; База данных Oracle обрабатывает это число как количество дней.

Добавить одну дату к другой или вычесть ее из другой, как в l_hiredate - SYSDATE.
Используйте встроенную функцию, чтобы «переместить» дату на указанное количество месяцев или на другую дату в течение недели.

Вот несколько примеров арифметики даты с датой и числом (во всех случаях предполагается, что переменная l_date была объявлена ​​как DATE):

Set a local variable to tomorrow’s date: 



l_date := SYSDATE + 1;


Move back one hour:



l_date := SYSDATE - 1/24;


Move ahead 10 seconds:



l_date := SYSDATE + 10 / (60 * 60 * 24);

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

    DECLARE
       l_date1   DATE := SYSDATE;
       l_date2   DATE := SYSDATE + 10;
    BEGIN
       DBMS_OUTPUT.put_line (
          l_date2 - l_date1);
       DBMS_OUTPUT.put_line (
          l_date1 - l_date2);
    END;

возвращает следующий вывод:

10 -10

Kaushik Nayak
8 апреля 2018 в 06:58
0

Можно размещать содержимое с другого веб-сайта, но вы также должны отдать ему должное: добавьте ссылку на oracle.com/technetwork/issue-archive/2012/12-jan/…

APC
8 апреля 2018 в 07:37
1

@KaushikNayak - на самом деле я не думаю, что приемлемо строить ответ путем оптовой вырезки и вставки с другого сайта, особенно потому, что его первоначальный автор отвечает на вопросы в StackOverflow.

Anuj Arora
8 апреля 2018 в 08:17
0

Я просто пытался ему помочь...... код лучше понять, если ты напишешь его сам, а не когда скопируешь его из coderhelper @APC

APC
8 апреля 2018 в 08:22
0

Вырезание и вставка чужой работы (дословно и без подтверждения) кажется странным способом побудить кого-то написать свой собственный код. Кроме того, этот ответ не касается реальных проблем ОП. Было бы лучше, если бы вы действительно написали правильный ответ, сосредоточенный на вопросе, как это сделал KaushikNayak.

Anuj Arora
8 апреля 2018 в 09:03
0

Это может не воодушевить вас... но для меня получение дополнительной информации всегда помогает мне попробовать кодирование самостоятельно.

Kaushik Nayak
8 апреля 2018 в 09:09
1

Ануж, я понимаю твои мысли. Но есть определенные стандарты, поддерживаемые ответами на этом сайте, в отличие от любых других технических форумов в Интернете. Ваш ответ может быть хорошим, но определенно бесполезным. Итак, чтобы избежать дальнейших отрицательных голосов и комментариев и аргументов в стиле Facebook, я бы посоветовал вам удалить этот ответ. Не обижайся дружок..хорошего дня...