Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Uruchom, aby sprawdzić duplikaty

Generalnie nie można wymusić tego rodzaju ograniczenia w wyzwalaczu. Będziesz musiał użyć ograniczenia.

Problem, który napotkasz, jeśli spróbujesz użyć wyzwalacza, polega na tym, że zazwyczaj napotkasz wyjątek „tabela mutacji”. Ogólnie rzecz biorąc, wyzwalacz na poziomie wiersza w tabeli A (tj. properties ) nie może wykonać zapytania do tabeli A. Możesz obejść ten problem, tworząc pakiet, tworząc kolekcję w tym pakiecie, inicjując kolekcję w wyzwalaczu instrukcji before, zapisując klucze, które są wstawiane lub aktualizowane do kolekcji w wyzwalaczu na poziomie wiersza , a następnie iterowanie przez elementy kolekcji w wyzwalaczu instrukcji after i wydawanie odpowiedniego DML względem tabeli. Wiąże się to jednak z dużą ilością ruchomych elementów i dużą złożonością (chociaż złożoność jest zmniejszona, jeśli korzystasz z 11g i możesz zamiast tego użyć złożonego wyzwalacza).

Ponadto, jeśli spróbujesz użyć wyzwalacza, napotkasz problemy w środowiskach wielu użytkowników. Jeśli użytkownik A wstawi wiersz w jednej sesji, a użytkownik B wstawi zduplikowany wiersz w innej sesji przed zatwierdzeniem przez użytkownika A, żaden wyzwalacz sesji nie wykryje zduplikowanego wiersza. Potencjalnie można obejść ten problem, jawnie blokując wiersz w tabeli nadrzędnej w celu serializacji wstawek do tabeli (celowo, aby aplikacja działała wolniej i była mniej skalowalna). Ale ograniczenie byłoby znacznie bardziej wydajnym i praktycznym rozwiązaniem.

Biorąc to wszystko pod uwagę, jeśli wstawiasz tylko jeden wiersz za pomocą INSERT ... VALUES składni i ogranicz się do jednej sesji, Twój wyzwalacz wydaje się działać

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dziedziczenie w projektowaniu baz danych

  2. Zapytanie w Oracle o uruchomienie sum

  3. ZABLOKOWANY wątek podczas wykonywania procedury Oracle z klasy Java

  4. Jak dynamicznie utworzyć zmienną o typie danych tabeli?

  5. Jak używać ograniczeń sprawdzania Oracle, aby ograniczyć liczbę rejestracji?