【问题标题】:SQL Using Multiple Triggers With Each OtherSQL 相互使用多个触发器
【发布时间】:2015-04-22 21:58:54
【问题描述】:

大家好,我正在创建一个用于管理系统实用程序的数据库。我的数据库有 3 个表:Users、Utilites 和 Files(将 Files 表排除在外,因为问题不应该影响它)。

表格

CREATE TABLE USERS ( 
User_id Number(38,0) NOT NULL PRIMARY KEY, 
User_name char(18) NULL , 
User_pass varchar(18) NULL , 
Storage_Size varchar(18) NULL , 
Memory_Usage Number(38,0) NULL 
);

CREATE TABLE UTILITIES ( 
Utility_id Number(38,0) NOT NULL PRIMARY KEY, 
Utility_Name varchar(18) NULL , 
Cost Number(38,0) NULL , 
Running char(4) NULL , 
User_id Number(38,0) NULL , 
);

触发器

//触发对所有UTILITIES的成本求和:

CREATE OR REPLACE TRIGGER memory_after_insert 
AFTER INSERT OR UPDATE OR DELETE
    ON UTILITIES
BEGIN
   UPDATE USERS
   SET MEMORY_USAGE = (SELECT SUM(COST) FROM UTILITIES WHERE USERS.USER_ID = UTILITIES.USER_ID);
END;

//触发对所有文件的成本求和

CREATE OR REPLACE TRIGGER storage_after_insert 
AFTER INSERT OR UPDATE OR DELETE
    ON FILES
BEGIN
  UPDATE USERS
  SET STORAGE_USAGE = (SELECT SUM(FILE_SIZE) FROM FILES WHERE USERS.USER_ID = FILES.USER_ID);
END;

现在我想创建一个触发器,在 INSERT into USERS(用户创建)时将 INSERT into UTILITIES 所有系统实用程序(我有 X 个默认实用程序,我希望每个用户都拥有)

我想出的示例触发器:

CREATE OR REPLACE TRIGGER users_after_insert
  AFTER INSERT ON USERS
  FOR EACH ROW
BEGIN
  INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, COST)
  VALUES
  ('Javaw.exe', 'YES', :new.USER_ID, seq_utility_id.nextval, round(dbms_random.value(25000, 100000)));
  INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, COST)
  VALUES
  ('Firefox.exe', 'YES', :new.USER_ID, seq_utility_id.nextval, round(dbms_random.value(60000, 200000)));
END;

当我的数据库中有这个触发器时,它会导致我的其他触发器混乱。我收到以下错误:

ORA-04091: table STUDENT052.USERS is mutating, trigger/function may not see it
ORA-06512: at "STUDENT052.MEMORY_AFTER_INSERT", line 2
ORA-04088: error during execution of trigger 'STUDENT052.MEMORY_AFTER_INSERT'
ORA-06512: at "STUDENT052.USERS_AFTER_INSERT", line 2
ORA-04088: error during execution of trigger 'STUDENT052.USERS_AFTER_INSERT'

在添加第三个触发器之前,其他两个触发器工作正常。我认为问题在于这个触发器。如果有人对如何解决此问题有任何了解,将不胜感激!谢谢!

【问题讨论】:

  • 您是在 DBA dba.stackexchange.com/questions/98592/… 上发布基本相同问题的同一个人吗?或者你们俩只是在做同样的家庭作业?您是否有理由在这里使用触发器而不是使用存储过程?
  • 确实是我的实验室合作伙伴之一发布了该内容。并回答为什么我们使用触发器而不是程序很好,这就是它的设置方式。那么,如果将触发器转换为过程,过程会是什么样子呢?我几乎没有使用过程序。
  • ora-04091 table is Mutating-ORA-04091: table name is mutatingHow to avoid ORA-04091 error within a trigger 和...的可能重复项...来吧 - 看看右侧页面的顶部。看到里面有“搜索”字样的方框了吗?在其中输入“ORA-04091”,按回车键,你会看到一堆东西。胃口大开!

标签: sql database oracle triggers


【解决方案1】:

首先,您的前两个查询存在问题。当您使用内存使用情况更新 USERS 表时,没有 where 条件。您应该添加:

WHERE USERS.User_id = :new.User_id;

否则,即使您只想更新单个用户记录,整个表也会被锁定。

CREATE OR REPLACE TRIGGER memory_after_insert 
AFTER INSERT OR UPDATE OR DELETE
    ON UTILITIES
BEGIN
   UPDATE USERS
   SET MEMORY_USAGE = (SELECT SUM(COST) FROM UTILITIES WHERE USERS.USER_ID = UTILITIES.USER_ID) WHERE USERS.User_id = :new.User_id;
END;

我认为您收到错误 (users_after_insert) 的原因是因为您的第一个触发器会在您为用户插入新的默认实用程序时相互触发,进而锁定整个 USERS 表。因此,进行此更改应该可以解决您的问题。

【讨论】:

    【解决方案2】:

    我创建了一个使用 2 个更新语句的过程。您可以查看它是否满足您的需求,创建触发器并将值插入实用程序表中。

    SQL> CREATE OR REPLACE TRIGGER users_after_insert
      2    AFTER INSERT ON USERS
      3    FOR EACH ROW
      4  BEGIN
      5    INSERT INTO UTILITIES (UTILITY_NAME, RUNNING, USER_ID, UTILITY_ID, COST)
      6    VALUES
      7    ('Javaw.exe', 'YES', :new.USER_ID,seq_utility_id.nextval, round(dbms_random.value(25000, 100000)));
      8
      9  END;
     10  /
    
    Trigger created.
    
    
    
    SQL> create or replace procedure sum_Data
    2  is
    3  begin
    4   UPDATE USERS
    5    SET Storage_Size  = (SELECT SUM(FILE_SIZE) FROM FILES WHERE USERS.USER_ID = FILES.USER_ID);
    6  UPDATE USERS
    7     SET MEMORY_USAGE = (SELECT SUM(COST) FROM UTILITIES WHERE USERS.USER_ID = UTILITIES.USER_ID);
    8  END;
    9  /
    
    procedure created.
    
    
    
    
    SQL> insert into users (user_id,user_name,user_pass) values (124,'ALPHA','xxxxxx');
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> select * from users;
    
       USER_ID USER_NAME          USER_PASS          STORAGE_SIZE       MEMORY_USAGE
    ---------- ------------------ ------------------ ------------------ ------------
           124 ALPHA              xxxxxx
    
    SQL> select * from utilities;
    
    UTILITY_ID UTILITY_NAME             COST RUNN    USER_ID
    ---------- ------------------ ---------- ---- ----------
            10 Javaw.exe               49780 YES         124
    
    SQL>
    

    【讨论】:

      猜你喜欢
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 2018-08-28
      • 2021-07-29
      • 1970-01-01
      相关资源
      最近更新 更多