在 PL/SQL 中触发
trigger in PL/SQL
给出了两个表格:
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'
?
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
PL/SQL
标签提示你使用Oracle数据库。
您说还有一个 table、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>
你定义 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
);
现在两个列都不能独立更新,并且在更新基础时自动更新。您将它们用作 select 的普通列,但不要在插入或更新中引用它们。而且不需要触发器。
参见fiddle。注意:您没有指定您使用的 Oracle 版本。这需要 11gR1 或更高版本。
给出了两个表格:
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'
?
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
PL/SQL
标签提示你使用Oracle数据库。
您说还有一个 table、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>
你定义 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
);
现在两个列都不能独立更新,并且在更新基础时自动更新。您将它们用作 select 的普通列,但不要在插入或更新中引用它们。而且不需要触发器。
参见fiddle。注意:您没有指定您使用的 Oracle 版本。这需要 11gR1 或更高版本。