Du kan i allmänhet inte genomdriva denna typ av begränsning i en utlösare. Du skulle behöva använda en begränsning.
Problemet du kommer att möta om du försöker använda en trigger är att du i allmänhet kommer att stöta på ett "muterande tabell"-undantag. I allmänhet en utlösare på radnivå i tabell A (d.v.s. properties
) kan inte fråga tabell A. Du kan kringgå det problemet genom att skapa ett paket, skapa en samling i det paketet, initiera samlingen i en before-utlösare, skriva nycklarna som infogas eller uppdateras i samlingen i en utlösare på radnivå , och sedan iterera genom elementen i samlingen i en efter-satsutlösare och utfärda lämplig DML mot tabellen. Detta innebär dock en hel del rörliga bitar och en hel del komplexitet (även om komplexiteten minskar om du är på 11g och kan använda en sammansatt trigger istället).
Dessutom, om du försöker använda en utlösare, kommer du att stöta på problem i miljöer med flera användare. Om användare A infogar en rad i en session och användare B infogar en dubblettrad i en annan session innan användare A commiterar, kommer ingen av sessionens utlösare att upptäcka dubblettraden. Du kan eventuellt komma runt den här typen av problem genom att explicit låsa en rad i den överordnade tabellen för att serialisera inlägg i tabellen (avsiktligt göra programmet långsammare och mindre skalbart). Men en begränsning skulle vara en mycket mer effektiv och praktisk lösning.
Med detta sagt, om du bara infogar en rad med hjälp av INSERT ... VALUES
syntax och begränsa dig till en enda session, verkar din trigger fungera
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'