sql >> Database >  >> RDS >> Oracle

Trigger om te controleren op duplicaten

U kunt dit soort beperkingen in het algemeen niet afdwingen in een trigger. Je zou een beperking moeten gebruiken.

Het probleem dat u tegenkomt als u een trigger probeert te gebruiken, is dat u over het algemeen een uitzondering voor "muterende tabel" tegenkomt. Over het algemeen een trigger op rijniveau in tabel A (d.w.z. properties ) kan geen query uitvoeren op tabel A. U kunt dat probleem omzeilen door een pakket te maken, een verzameling in dat pakket te maken, de verzameling te initialiseren in een trigger voor de instructie, en de sleutels die in de verzameling zijn ingevoegd of bijgewerkt in een trigger op rijniveau te schrijven , en vervolgens de elementen van de verzameling doorlopen in een trigger na de instructie en de juiste DML tegen de tabel afgeven. Dit omvat echter een heleboel bewegende stukken en een heleboel complexiteit (hoewel de complexiteit wordt verminderd als je op 11g werkt en in plaats daarvan een samengestelde trigger kunt gebruiken).

Als u bovendien een trigger probeert te gebruiken, zult u problemen tegenkomen in omgevingen met meerdere gebruikers. Als gebruiker A een rij invoegt in een sessie en gebruiker B een dubbele rij in een andere sessie invoegt voordat gebruiker A zich vastlegt, zal de trigger van geen van beide sessies de dubbele rij detecteren. U kunt dit soort problemen mogelijk omzeilen door expliciet een rij in de bovenliggende tabel te vergrendelen om invoegingen in de tabel te serialiseren (waardoor de toepassing met opzet langzamer en minder schaalbaar wordt). Maar een beperking zou een veel efficiëntere en praktischere oplossing zijn.

Dat gezegd hebbende, als u alleen enkele rijen invoegt met de INSERT ... VALUES syntaxis en beperk jezelf tot een enkele sessie, je trigger lijkt te werken

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'


  1. Converteer minuten naar HH24:MI-formaat

  2. Hoe parameter doorgeven in JDBC-query voor het maken van een tabel?

  3. Opgeslagen procedurefout PLS-00201:identifier 'UTL_HTTP' moet worden gedeclareerd

  4. Inleiding tot failover voor MySQL-replicatie - de 101 Blog