Отрегулируйте строки таблицы после модификаций (Delete, Insert Update) в Oracle - PullRequest
1 голос
/ 26 марта 2019

В таблице «Типы» порядок строк определяется полем «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 ''
  */

Я ожидаю, что одно решение обеспечит операцию триггера или другой подход к целостности поля заказа. Я думаю о том, чтобы использовать структуру Index-Organized Table, но не уверен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...