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

Auslöser zum Suchen nach Duplikaten

Sie können diese Art von Einschränkung im Allgemeinen nicht in einem Trigger erzwingen. Sie müssten eine Einschränkung verwenden.

Das Problem, mit dem Sie konfrontiert werden, wenn Sie versuchen, einen Trigger zu verwenden, besteht darin, dass Sie im Allgemeinen auf eine Ausnahme „Mutating Table“ stoßen. Im Allgemeinen ist ein Trigger auf Zeilenebene für Tabelle A (d. h. properties ) kann Tabelle A nicht abfragen. Sie können dieses Problem umgehen, indem Sie ein Paket erstellen, eine Sammlung in diesem Paket erstellen, die Sammlung in einem Before-Statement-Trigger initialisieren und die Schlüssel schreiben, die in die Sammlung eingefügt oder in einem Trigger auf Zeilenebene aktualisiert werden , und dann die Elemente der Sammlung in einem After-Statement-Trigger durchlaufen und die entsprechende DML für die Tabelle ausgeben. Dies beinhaltet jedoch eine ganze Menge bewegender Teile und eine ganze Menge Komplexität (obwohl die Komplexität reduziert ist, wenn Sie auf 11g sind und stattdessen einen zusammengesetzten Trigger verwenden können).

Wenn Sie versuchen, einen Trigger zu verwenden, treten außerdem Probleme in Umgebungen mit mehreren Benutzern auf. Wenn Benutzer A eine Zeile in einer Sitzung einfügt und Benutzer B eine doppelte Zeile in einer anderen Sitzung einfügt, bevor Benutzer A festschreibt, erkennt keiner der Trigger der Sitzung die doppelte Zeile. Sie können diese Art von Problem möglicherweise umgehen, indem Sie eine Zeile in der übergeordneten Tabelle explizit sperren, um Einfügungen in die Tabelle zu serialisieren (was die Anwendung absichtlich langsamer und weniger skalierbar macht). Aber eine Beschränkung wäre eine viel effizientere und praktischere Lösung.

Abgesehen davon, wenn Sie nur einzelne Zeilen einfügen, indem Sie die INSERT ... VALUES verwenden Syntax verwenden und sich auf eine einzelne Sitzung beschränken, scheint Ihr Trigger zu funktionieren

SQL> ed
Wrote file afiedt.buf

  1  create table Properties(
  2          idProperties number(10) NOT NULL,
  3          Address_FK number(20),
  4          Ownership_FK number(20)
  5* )
SQL> /

Table created.

SQL> CREATE OR REPLACE TRIGGER Check_Duplicate
  2  before insert or update on properties
  3  FOR each ROW
  4
  5  declare
  6  v_dup number;
  7
  8  begin
  9      select count(idProperties) INTO v_dup from properties where Address_FK=
:NEW.Address_FK and
 10       Ownership_FK=:NEW.Ownership_FK;
 11
 12   if v_dup > 0 then
 13     Raise_Application_Error (-20100, 'This property already exists. The inse
rt is cancelled.');
 14  end if;
 15  end;
 16  /

Trigger created.

SQL> insert into properties values( 1, 10, 100 );

1 row created.

SQL> insert into properties values( 2, 10, 100 );
insert into properties values( 2, 10, 100 )
            *
ERROR at line 1:
ORA-20100: This property already exists. The insert is cancelled.
ORA-06512: at "SCOTT.CHECK_DUPLICATE", line 9
ORA-04088: error during execution of trigger 'SCOTT.CHECK_DUPLICATE'