【发布时间】:2018-09-10 14:39:32
【问题描述】:
我用游标创建过程,我想通过更新触发器调用它,但它失败了。错误消息已翻译。在这个过程中,我使用游标检查列 STATE 中的所有行是否具有相同的值,如果条件为真,我在表 TRANSACTION 中再添加一行。 错误信息:
update TRANSACTIONS
set state = 'accept'
where ORDER_ID = 8
Error report -
ORA-04091: table ADMIN.TRANSACTIONS is changing, trigger/function should not see it
ORA-06512: on "ADMIN.CON_API_PKG", line 57
ORA-06512: on "ADMIN.CON_API_PKG", line 67
ORA-06512: on "ADMIN.INSERT_FINAL_WORKPLACE", line 2
ORA-04088: error meanwhile preparing trigger 'ADMIN.INSERT_FINAL_WORKPLACE'
触发器:
CREATE OR REPLACE TRIGGER INSERT_FINAL_WORKPLACE
BEFORE UPDATE ON TRANSACTIONS
FOR EACH ROW
BEGIN
CON_API_PKG.CREATEFINISHTRANSACTION(:NEW.order_id);
END;
程序:
PROCEDURE createFinishTransaction
(
pi_tra_order_id IN TRANSACTIONS.ORDER_ID%TYPE
)
AS
BEGIN
DECLARE
var_o_all NUMBER;
var_o_act NUMBER;
var_product_id transactions.product_id%TYPE;
var_created transactions.created%TYPE;
var_note transactions.note%TYPE;
var_reporter_id transactions.reporter_id%TYPE;
var_phase transactions.phase%TYPE;
CURSOR cursor_orders IS
SELECT count(order_id) FROM transactions
WHERE order_id = pi_tra_order_id;
CURSOR cursor_order_act IS
SELECT count(order_id) FROM transactions
WHERE order_id = pi_tra_order_id
AND state = 'accept';
CURSOR cursor_mapper IS
SELECT product_id, created, note, reporter_id, phase FROM transactions
WHERE order_id = pi_tra_order_id;
BEGIN
OPEN cursor_orders;
FETCH cursor_orders INTO var_o_all;
CLOSE cursor_orders;
OPEN cursor_order_act;
FETCH cursor_order_act INTO var_o_act;
CLOSE cursor_order_act;
OPEN cursor_mapper;
FETCH cursor_mapper INTO var_product_id, var_created, var_note, var_reporter_id, var_phase;
CLOSE cursor_mapper;
IF var_o_all = var_o_act
AND
var_phase IS NULL
THEN
INSERT INTO transactions (transaction_id, product_id, created, note,workplace_id, reporter_id, order_id, phase)
VALUES
(
(SELECT MAX(transaction_id) FROM transactions)+1,
var_product_id,
CURRENT_TIMESTAMP,
var_note,
(SELECT fw.workplace_id FROM final_workplace fw WHERE var_product_id = fw.product_id),
var_reporter_id,
pi_tra_order_id,
'final'
);
END IF;
END;
END;
【问题讨论】:
-
您正在查询触发器正在触发的表(事务) - 这将导致问题asktom.oracle.com/pls/asktom/…
-
您是否尝试将触发器更改为
AFTER UPDATE..? -
是的,但这无济于事
-
您应该重新考虑和探索可以存储/访问所需数据的替代方法,而不是使用您的方法“在表 TRANSACTION 中再添加一行”。也许您可以创建一个单独的视图,其中包含您在触发器和 avoid 触发器调用的此过程中本质上执行的聚合之上的所有条件。此外,如果您可以重写应用程序代码中的业务逻辑而不是触发器来避免这些情况,则更为明智。此外,更喜欢单个语句而不是多个游标(打开/获取/关闭)
标签: sql oracle plsql database-trigger