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'