在“类型”表上,行顺序应由字段“ ordem”控制。
在修改(删除,插入或更新)任何数据之后,应调整其他行以确保内容正确无误。
为实现这种功能,我尝试编写触发器以两种类似的方式(I,II)更正值。
CREATE TABLE TYPES (
ID NUMBER PRIMARY KEY,
ARG_1 VARCHAR2(20) NOT NULL,
ARG_2 VARCHAR2(20) NOT NULL,
ORDEM NUMBER NOT NULL
);
-----------------------------------------------
-- I
-----------------------------------------------
CREATE OR REPLACE TRIGGER TGR_TYPES
AFTER INSERT OR UPDATE OR DELETE ON TYPES
DECLARE
V_NORDEM NUMBER := NEW.ORDEM;
CURSOR C_TYPES IS
SELECT ID, ORDEM
FROM TYPES
WHERE ORDEM >= V_NORDEM;
BEGIN
IF UPDATING OR INSERTING THEN
BEGIN
FOR R_TYPE IN C_TYPES LOOP
UPDATE TYPEA SET ORDEM = (ORDEM + 1) WHERE ID = R_TYPE.ID;
END LOOP;
END;
ELSE
DECLARE V_ORDEM NUMBER := 0;
BEGIN
FOR R_TYPE IN C_TYPES LOOP
UPDATE OSP_TP_ADDR_COMPLEMENTOS SET ORDEM = (V_ORDEM + 1) WHERE ID = R_COMPLEMENTO.ID;
END LOOP;
END;
END IF;
END;
/*
ERROR ON COMPILE:
ORA-04082: referências NEW ou OLD não permitidas nos gatilhos de nível de tabela
04082. 00000 - "NEW or OLD references not allowed in table level triggers"
*Cause: The trigger is accessing "new" or "old" values in a table trigger.
*Action: Remove any new or old references.
*/
-----------------------------------------------
-- II
-----------------------------------------------
CREATE OR REPLACE
TRIGGER TRG_TYPES
AFTER INSERT OR UPDATE OR DELETE ON TYPES
FOR EACH ROW
BEGIN
IF UPDATING OR INSERTING THEN
BEGIN
FOR TP IN (
SELECT *
FROM TYPES
WHERE ORDEM >= :NEW.ORDEM
) LOOP
UPDATE TYPES SET ORDEM = (ORDEM + 1) WHERE ID = TP.ID;
COMMIT;
END LOOP;
END;
ELSE
DECLARE V_ORDEM NUMBER := 0;
BEGIN
FOR TP IN (
SELECT *
FROM TYPES
ORDER BY ORDEM
) LOOP
UPDATE TYPES SET ORDEM = (V_ORDEM + 1) WHERE ID = TP.ID;
END LOOP;
END;
END IF;
END;
/*
ERROR ON UPDATE:
UPDATE TYPES
SET ORDEM = 14
WHERE ID=26
Relatório de erros -
ORA-04091: a tabela TYPES é mutante; talvez o gatilho/função não possa localizá-la
ORA-06512: em "", line 9
ORA-04088: erro durante a execução do gatilho ''
*/
我希望一种解决方案可以确保触发操作或其他方法来确保订单字段的完整性。我正在考虑调整索引组织表的结构,但不确定。