Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Cursor in einem Trigger

Wegen der Schleife (der eine Exit-Klausel fehlt – hoffentlich haben Sie diese beim Übersetzen in eine Frage verloren) werden Sie versuchen, einen Datensatz in pstn_matrix einzufügen für alle zeichnet der Cursor zurück, ob es passende :new.person_id gibt oder nicht; und wenn es eine Übereinstimmung gibt, führen Sie auch das update durch . Was wahrscheinlich nicht das ist, was Sie wollen, und Sie könnten unter anderem eine Einschränkungsverletzung erhalten. Sie setzen auch nicht Ihr Zählerfeld - wenn das nicht nullable ist, wird das einen Fehler verursachen. Aber Sie haben nicht gesagt, welche Fehler Sie erhalten, wenn überhaupt.

Wenn Sie dies über einen Auslöser tun müssen, können Sie entweder prüfen, ob es überhaupt eine Zeile für die neue Person gibt:

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

... oder verwenden Sie merge .

Aber ich mag dieses Modell nicht, und Sie richten das Potenzial für Datenabweichungen mit gleichzeitigen Änderungen an der Basistabelle ein. Der Versuch, eine solche Zählung aufrechtzuerhalten, ist nicht unbedingt so einfach, wie es scheint.

Normalerweise würde ich es vorziehen, dies zu einer Ansicht zu machen, die immer auf dem neuesten Stand ist und keinen Trigger benötigt, der die Dinge kompliziert:

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

Natürlich kann es sein, dass ich falsch interpretiere oder zu sehr vereinfache, was Ihre Basistabelle(n) tut und was Sie postn_matrix benötigen zum. Es scheint ein wenig trivial zu sein, sogar als Ansicht zu haben. Wenn Sie eine separate person haben und person_position Tabellen, dann können Sie einen äußeren Join hinzufügen, um Personen ohne Positionen zu sehen:

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;