如何编写一个触发器来检查一个值是不是已经在表中?

Posted

技术标签:

【中文标题】如何编写一个触发器来检查一个值是不是已经在表中?【英文标题】:how to write a trigger that checks if a value is already in the table?如何编写一个触发器来检查一个值是否已经在表中? 【发布时间】:2021-06-11 21:14:23 【问题描述】:

我想编写一个触发器来检查产品是否已经存在于给定的托盘中,如果存在,而不是添加新行,只需将值添加到旧行中

我有桌子:

ID(pk) product_ID(fk) number of product
1 15 14

例如,如果我想添加类似的新行(id:2,product_id:15,产品数量:13),我想得到类似的东西:

ID(pk) product_ID(fk) number of product
1 15 27

不是这样的:

ID(pk) product_ID(fk) number of product
1 15 14
2 15 13

我使用 orlace

【问题讨论】:

***.com/help/minimal-reproducible-example 我猜你可以用复合触发器来做到这一点。但是为什么不在插入上使用合并呢? 【参考方案1】:

向表中添加行意味着插入。如果您在 Id 和 product_id 列上都添加唯一索引,那么在尝试插入现有值时,应该会发生异常 dup_val_on_index。如果你插入并且在插入时得到 dup_val_on_index 异常,你可以通过更新语句覆盖它,不需要触发,所有可以在异常语句中的插入语句上完成

【讨论】:

【参考方案2】:

按照您的说法,我同意 Alex 的评论 - merge 而不是单独的 insert 和/或 update。我进一步建议您创建一个 procedure 用于将行插入表中。为什么?调用该过程比重新编写相同(长?)merge 更简单。

这是一个例子:

SQL> create table test
  2    (id          number constraint pk_test primary key,
  3     product_id  number,
  4     number_prod number
  5    );

Table created.

SQL> create or replace procedure p_ins_test
  2    (par_id          in test.id%type,
  3     par_product_id  in test.product_id%type,
  4     par_number_prod in test.number_prod%type
  5    )
  6  is
  7  begin
  8    merge into test t
  9      using (select  par_id          as id,
 10                     par_product_id  as product_id,
 11                     par_number_prod as number_prod
 12           from dual
 13          ) x
 14    on (x.product_id = t.product_id)
 15    when matched then update set
 16      t.number_prod = t.number_prod + x.number_prod
 17    when not matched then insert (id, product_id, number_prod)
 18      values (x.id, x.product_id, x.number_prod);
 19  end;
 20  /

Procedure created.

测试:

SQL> exec p_ins_test(1, 15, 14);

PL/SQL procedure successfully completed.

SQL> select * from test;

        ID PRODUCT_ID NUMBER_PROD
---------- ---------- -----------
         1         15          14

SQL> exec p_ins_test(2, 15, 13);

PL/SQL procedure successfully completed.

SQL> select * from test;

        ID PRODUCT_ID NUMBER_PROD
---------- ---------- -----------
         1         15          27

SQL> exec p_ins_test(3, 99, 10);

PL/SQL procedure successfully completed.

SQL> select * from test;

        ID PRODUCT_ID NUMBER_PROD
---------- ---------- -----------
         1         15          27
         3         99          10

SQL>

【讨论】:

以上是关于如何编写一个触发器来检查一个值是不是已经在表中?的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以检查我的流分析输入是不是已经在表中?

oracle触发器在表中插入新行时更新新的视图行

检查 postgresql 的返回查询中是不是存在值

如何检查表中是不是已经存在时间限制?

如何编写唯一约束作为触发器?

检查字符串的第一部分是否在表中的值列表中