【问题标题】:Oracle trigger before insert插入前的 Oracle 触发器
【发布时间】:2021-08-25 10:29:13
【问题描述】:

这是我的示例触发器

create or replace TRIGGER INVOICES_INSERT
BEFORE INSERT ON INVOICES 
FOR EACH ROW
BEGIN
    if :new.INVOICE_TYPE = 'Purchase'
    
    insert into Purchases (ID, Name, Type) Values (:new.ID, :new.Name, :new.Type)
END;

在我的示例触发器中,我在 Invoices 和 Purchases 表中都获得了记录。但是如果IF语句中满足条件,我只想将数据记录到Purchases表中。

是否可以在触发器中做到这一点。

【问题讨论】:

  • 我是否理解正确:您想要捕获所有发票“购买”插入并写入采购行而不是发票行?当人员或流程认为他们插入发票时,您希望将非采购行插入发票并将采购行插入采购,而流程或人员不知道这种情况发生?他们会认为他们插入了发票,而并非总是如此?
  • 如果我的假设是正确的,你为什么要这样做呢?为什么有人认为他们插入到一个表中,而数据转到另一个表中?您可以通过简单地应用 where 子句从发票表中选择所有购买和所有非购买。为了方便起见,您甚至可以创建显示一种数据或另一种数据的视图。那么为什么会有这个棘手的计划呢?

标签: sql oracle triggers


【解决方案1】:

你不能做你想做的事,不是那样的。为什么?因为触发器在插入 invoices 之前触发,这意味着无论您在触发器中放入什么,都会将行 插入到 invoices 表中。是的,您也可以(可选)在purchase 表中插入一行,但您不能避免插入invoices

说你不能那样做,我的意思是说,毕竟,还有另一种方法。如何?使用视图和代替触发器。这是一个例子。

示例表:

SQL> create table invoices
  2   (id       number,
  3    name     varchar2(10),
  4    type     varchar2(10));

Table created.

SQL> create table purchase
  2   (id       number,
  3    name     varchar2(10),
  4    type     varchar2(10));

Table created.

查看,一个简单的联合:

SQL> create or replace view v_invpur as
  2    select id, name, type from invoices
  3    union all
  4    select id, name, type from purchase;

View created.

而不是触发器:根据类型,它会在适当的表中插入一行:

SQL> create or replace trigger trg_ioi_vinvpur
  2    instead of insert on v_invpur
  3    for each row
  4  begin
  5    if :new.type = 'invoice' then
  6       insert into invoices (id, name, type)
  7         values (:new.id, :new.name, :new.type);
  8    elsif :new.type = 'purchase' then
  9       insert into purchase (id, name, type)
 10         values (:new.id, :new.name, :new.type);
 11    end if;
 12  end;
 13  /

Trigger created.

测试:

SQL> insert into v_invpur (id, name, type)
  2    values (1, 'Little', 'purchase');

1 row created.

SQL> select * from invoices;

no rows selected

SQL> select * from purchase;

        ID NAME       TYPE
---------- ---------- ----------
         1 Little     purchase

SQL>

看到了吗? invoices 表中没有任何内容,但purchase 表中插入了一行。

【讨论】:

  • 感谢您的脚本,但它不起作用,因为 Invoices 表大约有 30 列,而 purchase 表大约少了 15 列。我在视图联合中遇到了问题。
  • 应该没问题。 UNION 要求 SELECT 语句具有相同数量的列并且它们的数据类型匹配。因此,而不是那些“丢失”的列,CAST NULL 到适当的数据类型。例如,cast (NULL as number) col1, cast (NULL as varchar2(10)) col2, ....
【解决方案2】:

有很多方法可以做到这一点。 . .如if。但是一个简单的方法是:

insert into Purchases (ID, Name, Type) 
    select :new.ID, :new.Name, :new.Type
    from dual
    where :new.INVOICE_TYPE = 'Purchase';

也就是说,“条件”逻辑可以只是 insert 的一部分。

【讨论】:

  • 此示例仅将数据插入到 Purchases 表中?
  • @Felichino 。 . .这只会将购买插入到Purchases 表中。
  • 是的,您的代码将在简单脚本或存储过程中运行,但在触发器中,它不起作用
  • @Felichino 。 . .我不知道你为什么会这么说。 INSERTs 在触发器中工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2018-04-11
  • 2014-06-28
相关资源
最近更新 更多