嘿所有我正在创建一个用于管理系统实用程序的数据库。我的数据库有3个表:Users,Utilites和Files(将Files表保留,因为问题不应该影响它)。
TABLES
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 ,
);
TRIGGERS
//触发汇总所有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;
//触发汇总所有FILES的费用
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中进入USERS(用户创建)将INSERT进入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'
在添加第三个触发器之前,其他2个触发器工作正常。我认为问题在于此触发器。如果有人知道如何解决这个问题,将不胜感激!谢谢!
答案 0 :(得分:0)
首先,您的前两个查询存在问题。使用内存使用情况更新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表。所以做这个改变应该可以解决你的问题。
答案 1 :(得分:0)
我创建了一个使用2更新语句的过程。您可以看到它是否符合您的需求,创建触发器并将值插入实用程序表。
GC.GetTotalMemory()