PL/SQL 中的触发器

Posted

技术标签:

【中文标题】PL/SQL 中的触发器【英文标题】:trigger in PL/SQL 【发布时间】:2020-06-06 03:57:55 【问题描述】:

给出了两个表:

1)

employee(eno,ename,basic,da,gross)
da=basic*(5.0/100)
gross = basic+da

2)

sal_hist(eno, sys_dt, old_basic)

当我更新员工的基本工资时,如何编写触发器来更新'da''gross'

【问题讨论】:

此示例向您展示如何编写触发器:tutorialspoint.com/plsql/plsql_triggers.htm。这显示了如何从触发器更新另一个表:***.com/questions/14789223/… 【参考方案1】:

PL/SQL标签建议你使用Oracle数据库。

你说还有一张桌子,sal_hist,但是 - 你没有说如何处理它。我想你想保存旧的基本工资。

在这种情况下,触发器如下所示:

SQL> create or replace trigger trg_biu_emp
  2    before insert or update on employee
  3    for each row
  4  begin
  5    insert into sal_hist(eno, sys_dt, old_basic) values
  6      (:new.eno, sysdate, :old.basic);
  7
  8    :new.da := :new.basic * 5 / 100;
  9    :new.gross := :new.basic + :new.da;
 10  end;
 11  /

Trigger created.

让我们看看它是如何工作的:

SQL> select * From employee;

       ENO ENAME      BASIC         DA      GROSS
---------- ----- ---------- ---------- ----------
         1 Scott        100          0          0
         2 Tiger        500          0          0

SQL> select * From sal_hist;

no rows selected

SQL> update employee set basic = 200 where eno = 1;

1 row updated.

SQL> insert into employee (eno, ename, basic) values (3, 'King', 1000);

1 row created.

SQL> select * From employee;

       ENO ENAME      BASIC         DA      GROSS
---------- ----- ---------- ---------- ----------
         1 Scott        200         10        210
         2 Tiger        500          0          0
         3 King        1000         50       1050

SQL> select * From sal_hist;

       ENO SYS_DT               OLD_BASIC
---------- ------------------- ----------
         1 06.06.2020 11:10:49        100
         3 06.06.2020 11:12:07

SQL>

【讨论】:

【参考方案2】:
CREATE  DEFINER=`root`@`localhost` TRIGGER `TRIGGERNAME` AFTER UPDATE ON `employee` FOR EACH ROW 

BEGIN

SET employee.da = employee.basic*(5.0/100)
SET employee.gross = employee.basic + (employee.basic*(5.0/100))

END

【讨论】:

虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。【参考方案3】:

你定义它们的方式 da 和 Gross 都可以直接从 base 导出。但是,作为标准列,我可以直接更新它们中的任何一个。如果这不是可取的,那么您可以将它们声明为虚拟列。

alter table employee drop (da, gross); 

alter table employee add ( 
                  da    generated always  as base * 0.05 virtual
                , gross generated always  as base * 1.05 virtual 
                );  

现在两列都不能独立更新,并且在更新基础时都会自动更新。您将它们用作选择的普通列,但不要在插入或更新中引用它们。而且不需要触发器。

见fiddle。注意:您没有指定您使用的 Oracle 版本。这需要 11gR1 或更高版本。

【讨论】:

以上是关于PL/SQL 中的触发器的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 PL/SQL 中的触发器发送电子邮件

如何从 PL/SQL 中的触发器回滚列

PL/SQL 触发器中的 SELECT 语句返回 null

PL/SQL 如何比较触发器中的表达式?

在 PL/SQL 中的触发器内调用函数

触发器中的 Oracle PL/SQL 游标