Oracle
 sql >> Base de données >  >> RDS >> Oracle

curseur dans un déclencheur

En raison de la boucle (qui manque une clause de sortie - j'espère que vous venez de perdre cette traduction en une question), vous allez essayer d'insérer un enregistrement dans pstn_matrix pour chaque enregistrer les retours du curseur, s'il existe des :new.person_id correspondants ou non; et s'il y a correspondance, vous ferez également la update . Ce qui n'est probablement pas ce que vous voulez, et vous pourriez obtenir une violation de contrainte entre autres choses. Vous ne définissez pas non plus votre champ de compteur - si ce n'est pas nullable, cela entraînera une erreur. Mais vous n'avez pas dit quelles erreurs, le cas échéant, vous obtenez.

Si vous devez le faire via un déclencheur, vous pouvez soit vérifier s'il y a une ligne pour la nouvelle personne :

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;
  ...

... ou utilisez merge .

Mais je n'aime pas ce modèle, et vous configurez le potentiel de divergences de données avec des modifications simultanées de la table de base. Essayer de maintenir un compte comme celui-ci n'est pas nécessairement aussi simple qu'il n'y paraît.

Je préfère généralement en faire une vue, qui sera toujours à jour et n'a pas besoin du déclencheur pour compliquer les choses :

create view postn_matrix as
  select person_id, count(*)
  from basetable
  group by person_id;

Bien sûr, j'interprète peut-être mal ou je simplifie à l'excès ce que font vos tables de base et ce dont vous avez besoin postn_matrix pour. Cela semble un peu trivial à avoir même comme point de vue. Si vous avez une person distincte et person_position tables, par exemple, vous pouvez ajouter une jointure externe pour voir les personnes sans poste :

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;