我有这些表
CELL(CellId,x0,y0,x1,y1,CurrentPhone#,MaxCalls)
电话(PhoneNo,x,y,PhoneState)
STATE_CHANGE(ChangeId,TimeStamp,PhoneNo,x,y,ChangeType)
我要创建此触发器(触发器是必需的)
更改最大活动呼叫数:蜂窝电话网络可能会减少与单个小区相关的最大活动呼叫数,以解决问题( > CELL 表中的MaxCalls 值。单个单元格的 MaxCalls 属性的更新可能会导致 CELL 表中的 MaxCalls 值变得小于该数字的不一致情况当前活动电话(PhoneState ='Active')在所考虑的小区中。如果是这样,相应的 MaxCalls 属性需要使用所考虑的单元格中当前活动电话的数量(PhoneState ='Active')进行更新
我写了这个触发器
create or replace trigger CELL_T1
AFTER UPDATE OF MAXCALLS ON CELL
BEGIN
UPDATE CELL E1
SET E1.MAXCALLS=(
SELECT COO
FROM (SELECT E2.CELLID, COO
FROM CELL E2, (
SELECT CELLID, COUNT(*) COO
FROM CELL C2, TELEPHONE
WHERE PhoneState='Active' AND x<x1 AND x>=x0 AND y<y1 AND y>=y0
GROUP BY C2.CellId
)TW
WHERE E2.CELLID=TW.CELLID AND COO>E2.MAXCALLS
)
)
WHERE E1.CELLID IN (
SELECT C1.CELLID
FROM CELL C1, (
SELECT CELLID, COUNT(*) COO
FROM CELL C3, TELEPHONE
WHERE PhoneState='Active' AND x<x1 AND x>=x0 AND y<y1 AND y>=y0
GROUP BY C3.CellId
)TW1
WHERE C1.CELLID=TW1.CELLID AND COO>C1.MAXCALLS and e1.cellid=tw1.cellid
);
END;
编译没有问题的触发器;然后我写了更新声明:
UPDATE CELL SET MAXCALLS=MAXCALLS-2;
但我收到了这些错误:
ORA-06512: at "MATTEO.CELL_T1", line 2
ORA-04088: error during execution of trigger 'MATTEO.CELL_T1'
ORA-06512: at "MATTEO.CELL_T1", line 2
ORA-04088: error during execution of trigger 'MATTEO.CELL_T1'
ORA-06512: at "MATTEO.CELL_T1", line 2
ORA-04088: error during execution of trigger 'MATTEO.CELL_T1'
ORA-06512: at "MATTEO.CELL_T1", line 2
ORA-04088: error during execution of trigger 'MATTEO.CELL_T1'
ORA-06512: at "MATTEO.CELL_T1", line 2
ORA-04088: error during execution of trigger 'MATTEO.CELL_T1'
ORA-0
我的触发器中找不到任何错误;出了什么问题?
答案 0 :(得分:3)
问题很可能是你在这里进行递归更新。当你执行UPDATE时,你的触发器会执行另一个UPDATE,它会触发触发器,该触发器在永无止境的循环中执行另一个UPDATE。直到,甲骨文变得无聊并引发所有这些例外。
在这种情况下,实际上只有两种方法。
答案 1 :(得分:2)
虽然我知道这个问题(你的大学任务)的原因不再适用。其他人可能仍会遇到类似问题。
所以做这样的事情(没有在数据库中测试,只能动态编写)
CREATE OR REPLACE TRIGGER cell_t1
BEFORE UPDATE OF maxcalls ON cell
FOR EACH ROW
DECLARE
v_active_cnt NUMBER(20);
BEGIN
SELECT COUNT(*)
INTO v_active_cnt
FROM telephone
WHERE phonestate='Active'
AND x<:NEW.x1
AND x>=:NEW.x0
AND y<:NEW.y1
AND y>=:NEW.y0;
IF ( :NEW.maxcalls < v_active_cnt )
THEN
:NEW.maxcalls := v_active_cnt
END;
END;
这是做什么的
- 在telephone
表中查询当前修改的行标识的单元格中的活动电话数量(:NEW数据集)
- 检查修改后的maxcalls
值是否大于此数字,如果是,则相应地修改新的maxcalls
值
顺便说一下,这正是这些触发器的用途。