Vanwege de lus (die een exit-clausule mist - hopelijk ben je die net kwijt door dit in een vraag te vertalen) ga je proberen een record in te voegen in pstn_matrix
voor elke noteer de cursor returns, of er overeenkomende :new.person_id
. zijn of niet; en als er een overeenkomst is, doe je ook de update
. Wat waarschijnlijk niet is wat je wilt, en je kunt onder andere een beperkingsschending krijgen. U stelt ook uw tellerveld niet in - als dat niet nullable is, zal dat een fout geven. Maar je hebt niet gezegd welke fouten je krijgt.
Als je dit via een trigger moet doen, kun je controleren of er een rij is voor de nieuwe persoon:
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;
...
... of gebruik merge
.
Maar ik hou niet van dit model, en je stelt het potentieel voor gegevensverschillen in met gelijktijdige wijzigingen aan de basistabel. Een dergelijke telling proberen bij te houden is niet per se zo eenvoudig als het lijkt.
Ik zou er meestal de voorkeur aan geven om dit een weergave te maken, die altijd up-to-date is en de trigger niet nodig heeft om dingen te compliceren:
create view postn_matrix as
select person_id, count(*)
from basetable
group by person_id;
Het kan natuurlijk zijn dat ik verkeerd interpreteer of te eenvoudig simplificeer wat uw basistabel(len) doet en wat u nodig heeft postn_matrix
voor. Het lijkt een beetje triviaal om zelfs maar een uitzicht te hebben. Als je een aparte person
hebt en person_position
tabellen, bijvoorbeeld, dan kun je een outer join toevoegen om mensen zonder posities te zien:
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;