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;