Как изменить старые данные таблицы с триггером до вставки в Oracle? - PullRequest
0 голосов
/ 26 апреля 2018

если новая строка вставлена ​​в таблицу, если дублирующие строки уже присутствуют, я хочу объединить две строки в одну

таблица ТЕСТ ( столбец идентификатора, определенный как первичный ключ )

ID     ITEM     QUANTITY
--     ----     --------
1       KA1        5
2       KA2        2

если новая строка вставлена ​​в таблицу test со значениями (KA1,6), поскольку для элемента KA1 уже существующая новая строка должна быть вставлена ​​с общим количеством 11, а старая строка должна быть удалено.

Результат должен быть следующим:

ID     ITEM     QUANTITY
--     ----     --------
2       KA2        2
3       KA1       11

, где используются триггер и встроенная процедура:

CREATE OR REPLACE TRIGGER  MERG_DUP
BEFORE INSERT ON TEST
FOR EACH ROW
BEGIN
  FOR VAL IN(SELECT ID,ITEM,QUANTITY, FROM TEST)
  LOOP
  IF VAL.ITEM=:NEW.ITEM THEN
            :NEW.QUANTITY:=:NEW.QUANTITY+VAL.QUANTITY;
           XXI_MULTI_PR_REMOVE(VAL.ID);
        EXIT;
  END IF;
  END LOOP;
end; 
/


CREATE  OR REPLACE PROCEDURE XXI_MULTI_PR_REMOVE(ID number)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
L_TID NUMBER;
BEGIN
 L_TID:=ID;
  DELETE FROM  TEST WHERE ID=L_TID;
commit;
END;
/

1 Ответ

0 голосов
/ 26 апреля 2018

Вам не нужно использовать PRAGMA AUTONOMOUS_TRANSACTION, и не используйте COMMIT inline внутри ваших процедур.

Для вашего случая неплохо бы CREATE TABLE test со столбцом ID , определенным как number generated always as identity primary key.

Следовательно, можно использовать операторы в следующем порядке:

 SQL> CREATE TABLE test(
                  id       number generated always as identity primary key,
                  item     varchar2(100),
                  quantity int
 );
 /
 SQL> INSERT INTO test(item,quantity) VALUES ('KA1',5);
 SQL> INSERT INTO test(item,quantity) VALUES ('KA2',2);

 SQL> CREATE OR REPLACE PROCEDURE XXI_MULTI_PR_REMOVE( I_ITEM varchar2 ) IS
 BEGIN
  DELETE TEST WHERE ITEM = I_ITEM;
 END;
 /
 SQL> CREATE OR REPLACE TRIGGER MERG_DUP
 BEFORE INSERT ON TEST
 FOR EACH ROW
 DECLARE  
      v_qty NUMBER;
 BEGIN
    BEGIN
      SELECT SUM(NVL(QUANTITY,0)) INTO v_qty FROM TEST WHERE ITEM = :NEW.ITEM;
     EXCEPTION WHEN OTHERS THEN v_qty := NULL; 
    END;  
    IF ( v_qty IS NOT NULL ) THEN
        XXI_MULTI_PR_REMOVE(:NEW.ITEM);
       :NEW.QUANTITY:=:NEW.QUANTITY+v_qty;    
    END IF;
 END MERG_DUP;
 /
 SQL> INSERT INTO test(item,quantity) VALUES ('KA3',6);
 SQL> COMMIT;
 SQL> SELECT * FROM test;
...