A causa del ciclo (a cui manca una clausola di uscita - si spera che tu l'abbia appena perso traducendolo in una domanda) tenterai di inserire un record in pstn_matrix
per ogni record che il cursore restituisce, se ci sono :new.person_id
corrispondenti o no; e se c'è corrispondenza farai anche l'update
. Che probabilmente non è quello che vuoi e potresti ottenere una violazione dei vincoli tra le altre cose. Inoltre, non stai impostando il campo del contatore:se non è nullable, si verificherà un errore. Ma non hai detto quali errori stai ricevendo.
Se devi farlo tramite un trigger, puoi controllare se c'è una riga per la nuova persona:
DECLARE
v_temp postn_matrix.person_id%TYPE;
BEGIN
IF INSERTING THEN
select max(person_id) into v_temp
from postn_matrix
where person_id = :new.person_id;
if v_temp is null then
-- no record found, so insert one
insert into postn_matrix (person_id, position_count)
values (:new.person_id, 1);
else
-- record exists, so update
update postn_matrix ...
end if;
...
... o usa merge
.
Ma non mi piace questo modello e stai impostando il potenziale per discrepanze di dati con modifiche simultanee alla tabella di base. Cercare di mantenere un conteggio come questo non è necessariamente così semplice come sembra.
Di solito preferisco fare di questa una vista, che sarà sempre aggiornata e non ha bisogno del grilletto per complicare le cose:
create view postn_matrix as
select person_id, count(*)
from basetable
group by person_id;
Ovviamente, potrei interpretare erroneamente o semplificare eccessivamente ciò che fanno le tue tabelle di base e ciò di cui hai bisogno postn_matrix
per. Mi sembra un po' banale averla anche come vista. Se hai una person
separata e person_position
tabelle, ad esempio, puoi aggiungere un join esterno per vedere le persone senza posizioni:
create view postn_matrix as
select p.person_id, count(pp.position_id)
from person p
left join person_position pp on pp.person_id = p.person_id
group by p.person_id;