sql >> Database teknologi >  >> RDS >> Oracle

Trigger for at tjekke for dubletter

Du kan generelt ikke håndhæve denne form for begrænsning i en trigger. Du skal bruge en begrænsning.

Problemet, du vil stå over for, hvis du prøver at bruge en trigger, er, at du generelt vil støde på en "mutationstabel"-undtagelse. Generelt en trigger på rækkeniveau i tabel A (dvs. properties ) kan ikke forespørge tabel A. Du kan omgå dette problem ved at oprette en pakke, oprette en samling i den pakke, initialisere samlingen i en før-sætningsudløser, skrive nøglerne, der er indsat eller opdateret i samlingen i en trigger på rækkeniveau , og derefter iterere gennem elementerne i samlingen i en efter-sætningsudløser og udstede passende DML mod tabellen. Dette involverer dog en hel masse bevægelige brikker og en hel masse kompleksitet (selvom kompleksiteten reduceres, hvis du er på 11g og kan bruge en sammensat trigger i stedet).

Derudover, hvis du prøver at bruge en trigger, vil du støde på problemer i flerbrugermiljøer. Hvis bruger A indsætter en række i én session, og bruger B indsætter en dubletrække i en anden session, før bruger A forpligter sig, vil ingen af ​​sessionernes trigger registrere den dubletrække. Du kan potentielt omgå denne slags problemer ved eksplicit at låse en række i den overordnede tabel for at serialisere indsættelser i tabellen (med vilje gøre applikationen langsommere og mindre skalerbar). Men en begrænsning ville være en meget mere effektiv og praktisk løsning.

Når det er sagt, hvis du kun laver enkeltrækkeindsættelser ved hjælp af INSERT ... VALUES syntaks og begrænse dig selv til en enkelt session, ser din trigger ud til at virke

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. Undgå dobbelte anførselstegn i SQL 2005/2008

  2. Bulk upsert med SQLAlchemy

  3. Bring Your Own Cloud (BYOC) vs. dedikeret hosting hos ScaleGrid

  4. Datatabeller - Json output - PostgreSQL - Returnerer null