По принцип не можете да наложите този вид ограничение в тригер. Ще трябва да използвате ограничение.
Проблемът, с който ще се сблъскате, ако се опитате да използвате тригер, е, че обикновено ще срещнете изключение на "мутираща таблица". Като цяло, тригер на ниво ред на таблица A (т.е. properties
) не може да направи заявка за таблица A. Можете да заобиколите този проблем, като създадете пакет, създадете колекция в този пакет, инициализирате колекцията в тригер преди израз, напишете ключовете, които се вмъкват или актуализират в колекцията в тригер на ниво ред , и след това итерация през елементите на колекцията в задействане на оператор след и издаване на подходящ DML срещу таблицата. Това обаче включва много движещи се части и много сложност (въпреки че сложността е намалена, ако сте на 11g и вместо това можете да използвате комбиниран тригер).
Освен това, ако се опитате да използвате тригер, ще срещнете проблеми в среди с много потребители. Ако потребител A вмъкне ред в една сесия и потребител B вмъкне дублиран ред в друга сесия, преди потребител A да се ангажира, тригерът на нито една сесия няма да открие дублиращия се ред. Потенциално можете да заобиколите този вид проблем, като изрично заключите ред в родителската таблица, за да сериализирате вмъкванията в таблицата (умишлено правейки приложението по-бавно и по-малко мащабируемо). Но ограничението би било много по-ефективно и практично решение.
Всичко казано, ако правите само вмъквания на един ред, като използвате INSERT ... VALUES
синтаксис и се ограничите до една сесия, вашият тригер наистина работи
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'