Я хочу создать триггер, который применяет условие, которое в столбце подробности может быть изменено только через 3 дня после его размещения
CREATE TRIGGER BEFORE UPDATE
CREATE TRIGGER INSTEAD OF UPDATE
У меня есть столбцы OrderId
, Details
, OrderDate
Как я могу это сделать? Не могли бы вы помочь пожалуйста
2 ответа
Вот пример.
Сначала тестовый пример:
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
SQL> create table test
2 (orderid number primary key,
3 details varchar2(20),
4 orderdate date
5 );
Table created.
SQL> insert into test (orderid, details, orderdate)
2 select 1, 'test 1', date '2018-10-15' from dual union all
3 select 2, 'test 2', date '2018-10-22' from dual;
2 rows created.
SQL> select sysdate from dual;
SYSDATE
----------
23.10.2018
SQL> select * from test;
ORDERID DETAILS ORDERDATE
---------- -------------------- ----------
1 test 1 15.10.2018
2 test 2 22.10.2018
SQL>
Курок:
SQL> create or replace trigger trg_bu_test
2 before update of details on test
3 for each row
4 begin
5 if trunc(sysdate) - :new.orderdate > 3 then
6 raise_application_error(-20001, 'More than 3 days have passed; update is not allowed');
7 end if;
8 end;
9 /
Trigger created.
Тестирование:
SQL> -- ID = 1 - 8 days have passed, no update is allowed
SQL> update test set details = 'xxx' where orderid = 1;
update test set details = 'xxx' where orderid = 1
*
ERROR at line 1:
ORA-20001: More than 3 days have passed; update is not allowed
ORA-06512: at "SCOTT.TRG_BU_TEST", line 3
ORA-04088: error during execution of trigger 'SCOTT.TRG_BU_TEST'
SQL> -- ID = 2 - 1 day passed - update is allowed
SQL> update test set details = 'yyy' where orderid = 2;
1 row updated.
SQL>
Постскриптум Триггеры INSTEAD OF
(вы упомянули в своем вопросе) используются с представлениями; забудьте о них (в этом случае).
Попробуйте использовать AFTER Trigger
create or replace TRIGGER TR_details_update
AFTER UPDATE ON order_det
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
BEGIN
IF UPDATING THEN
IF NVL(:OLD.Details, 'XXX') <> NVL(:NEW.Details, 'XXX') AND :OLD.OrderDate <= TRUNC(SYSDATE) - 3 THEN
update order_det
set Details = :new.Details
where Details = :old.Details
and OrderId = :old.OrderId;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR (-20000,'Details must be changed within 3 days of order date');
END TR_details_update;
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.