Oracle
 sql >> Database >  >> RDS >> Oracle

cursore in un trigger

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;