简体   繁体   English

如何在 Oracle PL/SQL 中实现 AFTER INSERT 触发器?

[英]How to implement AFTER INSERT Trigger in Oracle PL/SQL?

I am trying to implement after insert trigger in PLSQL.我正在尝试在 PLSQL 中插入触发器后实现。
The goal is to check if there are multiple (>1) rows having specific status for each client.目标是检查是否有多个 (>1) 行具有每个客户端的特定状态。
If so I'd like to rise an exception and roll the insertion back.如果是这样,我想引发异常并将插入回滚。

I am struggling with implementing warning-free query, which causes error during insertion.我正在努力实现无警告查询,这会在插入过程中导致错误。
How could I manage this?我怎么能做到这一点?
Here is my implemented trigger which I guess needs some changes.这是我实现的触发器,我想需要一些更改。

CREATE TRIGGER blatrigger
    AFTER INSERT
    ON BLATABLE
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
DECLARE
    exception_name EXCEPTION;
    PRAGMA EXCEPTION_INIT (exception_name, -20999);
BEGIN
    if (select count(*) as counter from BLATABLE where CLIENTID = :NEW.CLIENTID and STATUS='PENDING').counter > 1
    THEN
        raise exception_name;
    END IF;
END;

Here is the table itself:这是表格本身:

create table BLATABLE
(
    ID            NUMBER(19) not null primary key,
    CLIENTID     NUMBER(10),
    CREATED       TIMESTAMP(6),
    STATUS        VARCHAR2(255 char)
);

The goal is to check if there are multiple (>1) rows having specific status for each client.目标是检查是否有多个 (>1) 行具有每个客户端的特定状态。 If so I'd like to rise an exception and roll the insertion back.如果是这样,我想引发异常并将插入回滚。

No need for a trigger.不需要触发器。 It looks like a simple unique constraint should get the job done here:看起来一个简单的唯一约束应该在这里完成工作:

create table blatable (
    id            number(19) not null primary key,
    clientid      number(10),
    created       timestamp(6),
    status        varchar2(255 char),
    constraint blaconstraint unique (clientid, status)
);

The unique constraint prevents duplicates on (clientid, status) across the whole table.唯一约束可防止整个表中的(clientid, status)重复。 If a DML operation (insert, update) attempts to generate a duplicate, an error is raised and the operation is rolled back.如果 DML 操作(插入、更新)尝试生成重复项,则会引发错误并回滚该操作。

If, on the other end, you want to allow only one "PENDING" status per user, then you can use a unique index as follows:另一方面,如果您希望每个用户只允许一个“PENDING”状态,那么您可以使用唯一索引,如下所示:

create unique index bla_index
    on blatable( (case when status = 'PENDING' then clientid end) );

Use a Statement Level Trigger, rather than a Row Level by removing FOR EACH ROW , and converting to your code as below :通过删除FOR EACH ROW并转换为您的代码,使用语句级别触发器,而不是行级别,如下所示:

CREATE OR REPLACE TRIGGER blatrigger
  AFTER INSERT ON BLATABLE
  REFERENCING NEW AS NEW OLD AS OLD

DECLARE
  counter        INT;
  exception_name EXCEPTION;
  PRAGMA EXCEPTION_INIT(exception_name, -20999);
BEGIN
  SELECT MAX(COUNT(*))
    INTO counter
    FROM BLATABLE
   WHERE STATUS = 'PENDING'
   GROUP BY CLIENTID;
     
  IF counter > 1 THEN
    RAISE exception_name;
  END IF;
END;
/

where在哪里

  • the SELECT statement need to be removed from IF .. THEN conditional SELECT 语句需要从IF .. THEN条件中删除
  • Most probably, the mutating table error would raise for Row Level Trigger case最有可能的是,对于 Row Level Trigger 情况,变异表错误会引发

Demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM