Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在一定条件下创建更新触发器?_Sql_Oracle_Oracle11g_Database Trigger - Fatal编程技术网

Sql 如何在一定条件下创建更新触发器?

Sql 如何在一定条件下创建更新触发器?,sql,oracle,oracle11g,database-trigger,Sql,Oracle,Oracle11g,Database Trigger,我想创建一个触发器,该触发器强制执行以下条件:声明为“详细信息”列只能在放置后3天内更改 我有OrderId,详细信息,OrderDate列 我该怎么做?你能帮忙吗?这里有一个例子 首先,测试用例: SQL> alter session set nls_date_format = 'dd.mm.yyyy'; Session altered. SQL> create table test 2 (orderid number primary key, 3 d

我想创建一个触发器,该触发器强制执行以下条件:声明为“详细信息”列只能在放置后3天内更改

我有
OrderId
详细信息
OrderDate

我该怎么做?你能帮忙吗?这里有一个例子

首先,测试用例:

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>
p.S.
而不是
触发器(您在问题中提到)用于视图;忘掉它们(在这种情况下)。

下面是一个例子

首先,测试用例:

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>

p.S.
而不是
触发器(您在问题中提到)用于视图;忘记它们(在这种情况下)。

尝试使用AFTER触发器

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;
创建或替换触发器TR\u详细信息\u更新
订单数据更新后
引用新旧相同
每行
开始
如果更新,则

如果NVL(:OLD.Details,'XXX')NVL(:NEW.Details,'XXX')和:OLD.OrderDate请尝试使用AFTER触发器

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;
创建或替换触发器TR\u详细信息\u更新
订单数据更新后
引用新旧相同
每行
开始
如果更新,则

如果NVL(:OLD.Details,'XXX')NVL(:NEW.Details,'XXX')和:OLD.OrderDate,您是否可以尝试自己创建它?甚至为更新触发器挖掘任何文档,比如,都会给你更多的想法/尝试,让你自己写这篇文章,而不是你目前所拥有的。你能尝试一下自己创建它吗?即使是为更新触发器挖掘任何文档,比如,也会给你比目前更多的想法/尝试,让你自己写这篇文章。为什么在
触发器之后是
,而不是在
触发器之前是
?在更新后触发器中,您还会做什么?为什么要在触发器中更新
?在代码中,您什么也不做。另外,您希望出现哪种例外情况?这应该是其他的一部分,而不是例外。我得到了变异错误。。所以我改成在触发后。。。我在块内进行了更新,但在我看到您的触发器后,这是不必要的…谢谢为什么在
触发器之后是
,而不是在
触发器之前是
?在更新后触发器中,您还会做什么?为什么要在触发器中更新
?在代码中,您什么也不做。另外,您希望出现哪种例外情况?这应该是其他的一部分,而不是例外。我得到了变异错误。。所以我改成在触发后。。。我在块内进行了更新,但在我看到你的触发器后,这是不必要的…谢谢一切都很好,以可以理解的方式解释,一步一步,非常感谢一切都很好,以可以理解的方式解释,一步一步,非常感谢