Это вероятное решение:
Я проверил его с помощью следующих таблиц:
CREATE TABLE CLAN_AFFILIATI(CLAN VARCHAR2(100),AFFILIATO VARCHAR2(100),RUOLO VARCHAR2(100));
CREATE TABLE CLAN (NOME VARCHAR2(100) ,NUMAFFILIATI NUMBER(10));
Вам нужен этот вспомогательный пакет.
CREATE OR REPLACE PACKAGE STORE_NOMES
AS
TYPE record_nomes IS RECORD (
nome VARCHAR2(100),
operation VARCHAR2(100) -- insert or delete
);
TYPE array_type_nomes IS TABLE OF record_nomes INDEX BY BINARY_INTEGER;
g_array_nomes array_type_nomes;
END STORE_NOMES;
/
Триггер на таблице CLAN:
CREATE OR REPLACE TRIGGER MODIFICANUMAFFILIATI
BEFORE INSERT OR UPDATE OF NUMAFFILIATI ON CLAN
FOR EACH ROW
DECLARE
l_CONT NUMBER:=0;
BEGIN
IF INSERTING THEN
-- prevent inserting <> 0
IF :new.NUMAFFILIATI <> 0 THEN
RAISE_APPLICATION_ERROR(-20016,'NUMERO ERRATO');
END IF;
ELSE
SELECT COUNT(*) INTO l_CONT
FROM CLAN_AFFILIATI
WHERE CLAN = :old.NOME;
IF l_CONT <> :new.NUMAFFILIATI THEN
RAISE_APPLICATION_ERROR(-20017,'NUMERO ERRATO');
END IF;
END IF;
END;
/
До триггера оператора в таблице CLAN_AFFILIATI:
CREATE OR REPLACE TRIGGER TRG_CLAN_AFFILIATI_BEFORE_STMT
BEFORE INSERT OR DELETE
ON CLAN_AFFILIATI
DECLARE
BEGIN
STORE_NOMES.g_array_nomes.DELETE;
END;
/
После триггера оператора в таблице CLAN_AFFILIATI:
CREATE OR REPLACE TRIGGER TRG_CLAN_AFFILIATI_AFTER_STMT
AFTER INSERT OR DELETE
ON CLAN_AFFILIATI
DECLARE
BEGIN
FOR i IN STORE_NOMES.g_array_nomes.FIRST..STORE_NOMES.g_array_nomes.LAST LOOP
IF(STORE_NOMES.g_array_nomes(i).operation = 'INSERTING') THEN
UPDATE CLAN
SET NUMAFFILIATI=NUMAFFILIATI+1
WHERE NOME = STORE_NOMES.g_array_nomes(i).NOME;
ELSIF(STORE_NOMES.g_array_nomes(i).operation = 'DELETING') THEN
UPDATE CLAN
SET NUMAFFILIATI=NUMAFFILIATI-1
WHERE NOME = STORE_NOMES.g_array_nomes(i).NOME;
END IF;
END LOOP;
END;
/
Триггер вставки / удаления строки в таблице CLAN_AFFILIATI:
CREATE OR REPLACE TRIGGER AGGIORNAMENTONUMAFFILIATI
BEFORE INSERT OR DELETE ON CLAN_AFFILIATI
FOR EACH ROW
DECLARE
l_CLAN_APPARTENENZA VARCHAR(20);
BEGIN
IF INSERTING THEN
SELECT NOME INTO l_CLAN_APPARTENENZA
FROM CLAN
WHERE NOME = :new.CLAN;
STORE_NOMES.g_array_nomes(STORE_NOMES.g_array_nomes.COUNT).nome := :new.CLAN;
STORE_NOMES.g_array_nomes(STORE_NOMES.g_array_nomes.LAST).operation := 'INSERTING';
ELSE
SELECT NOME INTO l_CLAN_APPARTENENZA
FROM CLAN
WHERE NOME = :old.CLAN;
STORE_NOMES.g_array_nomes(STORE_NOMES.g_array_nomes.COUNT).nome := :old.CLAN;
STORE_NOMES.g_array_nomes(STORE_NOMES.g_array_nomes.LAST).operation := 'DELETING';
END IF;
END;
/
Теперь работаем так (без ORACLE-EXCEPTION):
INSERT INTO CLAN(NOME, NUMAFFILIATI) VALUES('Antonio', 0);
INSERT INTO CLAN_AFFILIATI(CLAN,AFFILIATO,RUOLO) values('Antonio','Affiliato1','Ruolo1');
INSERT INTO CLAN_AFFILIATI(CLAN,AFFILIATO,RUOLO) values('Antonio','Affiliato2','Ruolo2');