在Oracle上进行修改(删除,插入更新)后,调整表行

时间:2019-03-26 14:40:22

标签: oracle plsql

在“类型”表上,行顺序应由字段“ 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 ''
  */

我希望一种解决方案可以确保触发操作或其他方法来确保订单字段的完整性。我正在考虑调整索引组织表的结构,但不确定。

0 个答案:

没有答案