我用游标创建了过程,但我想通过更新触发器来调用它,但是失败了。错误消息已翻译。在此过程中,我使用游标检查STATE列中是否所有行都具有相同的值,并且如果条件为true,则在表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;
答案 0 :(得分:0)
我将您的光标替换为 select ins ,并将您的程序更改为 AUTONOMOUS ,该程序可以工作,但是我建议您避免更新触发器中的同一表,也可能插入其他表中,例如:FINALIZED_TRANSACTIONS。
这是我的触发代码:
CREATE OR REPLACE TRIGGER INSERT_FINAL_WORKPLACE
BEFORE UPDATE
ON TRANSACTIONS
FOR EACH ROW
BEGIN
SELECT COUNT (ORDER_ID), COUNT (DECODE (STATE, 'accept', ORDER_ID, NULL))
INTO VAR_O_ALL, VAR_O_ACT
FROM TRANSACTIONS
WHERE ORDER_ID = PI_TRA_ORDER_ID;
IF VAR_O_ALL = VAR_O_ACT AND :NEW.ORDER_ID IS NULL
THEN
CON_API_PKG.CREATEFINISHTRANSACTION (
:NEW.ORDER_ID,
:NEW.PRODUCT_ID,
:NEW.NOTE,
:NEW.REPORTER_ID
);
END IF;
END;
这是我的程序代码:
CREATE OR REPLACE PROCEDURE CREATEFINISHTRANSACTION (
PI_TRA_ORDER_ID IN TRANSACTIONS.ORDER_ID%TYPE,
PI_PRODUCT_ID IN TRANSACTIONS.PRODUCT_ID%TYPE,
PI_NOTE IN TRANSACTIONS.NOTE%TYPE,
PI_REPORTER_ID IN TRANSACTIONS.REPORTER_ID%TYPE)
AS
PRAGMA AUTONOMOUS_TRANSACTION;
VAR_WORKPLACE_ID FINAL_WORKPLACE.WORKPLACE_ID%TYPE;
BEGIN
BEGIN
SELECT FW.WORKPLACE_ID
INTO VAR_WORKPLACE_ID
FROM FINAL_WORKPLACE FW
WHERE PI_PRODUCT_ID = FW.PRODUCT_ID;
EXCEPTION
WHEN OTHERS
THEN
--Handle exception by displaying dbms output or insert into a log table
ROLLBACK;
END;
INSERT
INTO TRANSACTIONS (
TRANSACTION_ID,
PRODUCT_ID,
CREATED,
NOTE,
WORKPLACE_ID,
REPORTER_ID,
ORDER_ID,
PHASE
)
VALUES (
(SELECT MAX (TRANSACTION_ID) FROM TRANSACTIONS) + 1,
PI_PRODUCT_ID,
CURRENT_TIMESTAMP,
PI_NOTE,
VAR_WORKPLACE_ID,
PI_REPORTER_ID,
PI_TRA_ORDER_ID,
'final');
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
--Handle exception by displaying dbms output or insert into a log table
ROLLBACK;
END;