【问题标题】:Error during trigger execution - ORA-06512 - ORA-04088触发器执行期间出错 - ORA-06512 - ORA-04088
【发布时间】:2013-11-29 23:51:46
【问题描述】:

我有这些表

CELL(CellId, x0, y0, x1, y1, CurrentPhone#, MaxCalls)
TELEPHONE(PhoneNo, x, y, PhoneState)
STATE_CHANGE(ChangeId, TimeStamp, PhoneNo, x, y, ChangeType)

我必须创建这个触发器(触发器是强制性的)

更改最大活动通话数蜂窝电话网络可能会减少与单个小区相关的最大活动通话数以管理问题(减少 MaxCalls CELL 表中的值)。更新单个单元格的 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
  1. 更新单元格
  2. SET MaxCalls = MaxCalls-2;

我在触发器中找不到任何问题;怎么了?

【问题讨论】:

  • 我无法创建视图或过程

标签: sql triggers oracle11g ora-06512 ora-04088


【解决方案1】:

问题很可能是您在此处进行递归更新。当您执行 UPDATE 时,您的触发器会执行另一个 UPDATE,这会触发触发器,该触发器会在一个永无止境的循环中执行另一个 UPDATE。直到,也就是说,Oracle 感到厌烦并引发所有这些异常。

在这种情况下,实际上只有两条出路。

  • 不要更新表并在视图(或其他东西)上使用INSTEAD OF DML trigger,这样触发器只会触发一次。
  • 将所有这些逻辑删除到存储过程中,并且根本不使用触发器。

【讨论】:

  • 这是关于触发器的大学作业,所以我必须使用触发器:(
  • 我问过教授,她对我说我必须使用触发器而不创建视图......我该怎么做?
  • 您的教授告诉您,您是否必须直接在表上使用更新触发器,该触发器会在表更新时触发,并且它本身会更新表? 叹息。你上什么大学?您不能同时更新表格和不更新表格,所以这似乎让您真正做疯狂的事情,以便做应该是一件简单的事情。我真的只能说祝你好运并继续检查;其他人可能有其他想法。
【解决方案2】:

虽然我知道这个问题(你的大学作业)的原因不再相关。其他人可能仍然有类似的问题。

  • 如果您需要在触发器中进行一致性检查,请在更新之前进行,而不是之后。
  • 仅检查您的语句实际修改的行。
  • 对于此类操作,请使用 ROW 触发器,而不是 STATEMENT 触发器
  • 使用“:OLD”和“:NEW”数据集而不是查询表

所以做这样的事情(不在数据库中测试,只在运行中编写)

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

顺便说一句,这正是这些触发器的用途。

【讨论】:

    猜你喜欢
    • 2017-03-26
    • 2015-08-06
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多