Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

cursor em um gatilho


Por causa do loop (que está faltando uma cláusula de saída - espero que você tenha perdido isso traduzindo isso em uma pergunta), você tentará inserir um registro em pstn_matrix para todos registre os retornos do cursor, se houver algum :new.person_id correspondente ou não; e se houver correspondência, você também fará a update . O que provavelmente não é o que você deseja, e você pode obter uma violação de restrição entre outras coisas. Você também não está definindo seu campo de contador - se isso não for anulável, ocorrerá um erro. Mas você não disse quais erros, se houver, você está recebendo.

Se você precisar fazer isso por meio de um gatilho, poderá verificar se há uma linha para a nova pessoa:
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 use merge .

Mas eu não gosto desse modelo, e você está configurando o potencial de discrepâncias de dados com modificações simultâneas na tabela base. Tentar manter uma contagem como essa não é necessariamente tão simples quanto parece.

Eu geralmente prefiro tornar isso uma visão, que estará sempre atualizada e não precisa do gatilho para complicar as coisas:
create view postn_matrix as
  select person_id, count(*)
  from basetable
  group by person_id;

Claro, posso estar interpretando mal ou simplificando demais o que sua(s) tabela(s) base(s) fazem e o que você precisa postn_matrix por. Parece um pouco trivial ter mesmo como vista. Se você tiver uma person separada e person_position tabelas, digamos, então você pode adicionar uma junção externa para ver pessoas sem posições:
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;