sql >> Base de Datos >  >> RDS >> Oracle

cursor en un gatillo

Debido al bucle (al que le falta una cláusula de salida; es de esperar que haya perdido eso al traducir esto en una pregunta), intentará insertar un registro en pstn_matrix para cada registre los retornos del cursor, si hay algún :new.person_id coincidente O no; y si hay una coincidencia, también hará la update . Lo que probablemente no sea lo que desea, y puede obtener una violación de restricción, entre otras cosas. Tampoco está configurando su campo de contador; si eso no es anulable, eso generará un error. Pero no ha dicho qué errores, si los hay, está recibiendo.

Si debe hacer esto a través de un activador, puede verificar si hay una fila para la nueva 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 use merge .

Pero no me gusta este modelo, y está configurando la posibilidad de discrepancias de datos con modificaciones simultáneas en la tabla base. Tratar de mantener un conteo como este no es necesariamente tan simple como parece.

Por lo general, prefiero hacer de esto una vista, que siempre estará actualizada y no necesita que el activador complique las cosas:

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

Por supuesto, puedo estar malinterpretando o simplificando en exceso lo que hace su(s) tabla(s) base y lo que necesita postn_matrix por. Parece un poco trivial tener incluso como vista. Si tiene una person separada y person_position tablas, digamos, luego puede agregar una combinación externa para ver personas sin posiciones:

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;