【问题标题】:How can I create a SQL trigger that updates a table based on another?如何创建基于另一个表更新表的 SQL 触发器?
【发布时间】:2022-01-21 08:23:34
【问题描述】:

我正在尝试在 Oracle 中创建一个 SQL 触发器,它会在每次插入或删除后计算表中的行,这些行满足具有特定值的特定行的条件。然后,应该用这个数字更新另一个表。

具体例子:我有一个employees表,当添加或删除一个员工时,我想统计该部门当前工作的员工人数,然后更新部门表以包含新的员工人数对于那个特定的部门。

有人有想法吗?我很难理解这个查询。

【问题讨论】:

  • 这样存储信息通常是个坏主意。当您需要这些信息时,为什么不直接计算部门的员工人数?

标签: oracle plsql triggers


【解决方案1】:

正如詹姆斯已经评论的那样,您根本不应该这样做。如果必须,请参阅以下示例:

示例表:

SQL> create table employees
  2    (deptno number,
  3     empno  number);

Table created.

SQL> create table emp_count
  2    (deptno number,
  3     cnt    number);

Table created.

触发器,它负责您的操作(插入、更新或删除行):

SQL> create or replace trigger trg_aiud_emp
  2    after insert or update or delete on employees
  3    for each row
  4  begin
  5    if inserting then
  6       merge into emp_count c
  7         using dual d
  8         on (:new.deptno = c.deptno)
  9       when matched then update set
 10         c.cnt = c.cnt + 1
 11       when not matched then insert (deptno, cnt)
 12         values (:new.deptno, 1);
 13    elsif deleting then
 14       update emp_count c set
 15         c.cnt = c.cnt - 1
 16         where c.deptno = :old.deptno;
 17    elsif updating then
 18       if :new.deptno <> :old.deptno then
 19          update emp_count c set
 20            c.cnt = c.cnt - 1
 21            where c.deptno = :old.deptno;
 22
 23          merge into emp_count c
 24            using dual d
 25            on (:new.deptno = c.deptno)
 26          when matched then update set
 27            c.cnt = c.cnt + 1
 28          when not matched then insert (deptno, cnt)
 29            values (:new.deptno, 1);
 30       end if;
 31    end if;
 32  end;
 33  /

Trigger created.

SQL>

一点测试:

SQL> insert into employees (deptno, empno) values (10, 7744);

1 row created.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        10       7744

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          1

SQL> insert into employees (deptno, empno)
  2    select 10, 8722 from dual union all
  3    select 20, 1234 from dual;

2 rows created.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        10       7744
        10       8722
        20       1234

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          2
        20          1

SQL>

SQL> update employees set deptno = 30 where empno = 7744;

1 row updated.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        30       7744
        10       8722
        20       1234

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          1
        20          1
        30          1

SQL> update employees set deptno = 10;

3 rows updated.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        10       7744
        10       8722
        10       1234

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          3
        20          0
        30          0

SQL>

SQL> delete from employees where empno = 7744;

1 row deleted.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        10       8722
        10       1234

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          2
        20          0
        30          0

SQL> delete from employees;

2 rows deleted.

SQL> select * From employees;

no rows selected

SQL> select * From emp_count;

    DEPTNO        CNT
---------- ----------
        10          0
        20          0
        30          0

SQL>

所有这些都没有什么大惊小怪的,因为您只需要一个简单、微小的视图

SQL> create or replace view v_emp_count as
  2    select deptno, count(*) cnt
  3    from employees
  4    group by deptno;

View created.

SQL> insert into employees (deptno, empno)
  2    select 10, 7744 from dual union all
  3    select 10, 8722 from dual union all
  4    select 20, 1234 from dual;

3 rows created.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        10       7744
        10       8722
        20       1234

SQL> select * From v_emp_count;

    DEPTNO        CNT
---------- ----------
        20          1
        10          2

SQL> update employees set deptno = 30 where empno = 7744;

1 row updated.

SQL> select * From employees;

    DEPTNO      EMPNO
---------- ----------
        30       7744
        10       8722
        20       1234

SQL> select * From v_emp_count;

    DEPTNO        CNT
---------- ----------
        30          1
        20          1
        10          1

结论:使用视图。

【讨论】:

  • 非常感谢您的回复!非常有见地和有用。祝您有美好的一天,感谢您的帮助!
猜你喜欢
  • 2022-01-15
  • 2020-07-26
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多