sql >> Databáze >  >> RDS >> Oracle

Spusťte kontrolu duplikátů

Obecně nemůžete vynutit tento druh omezení ve spouštěči. Budete muset použít omezení.

Problém, kterému budete čelit, když se pokusíte použít spouštěč, je ten, že obecně narazíte na výjimku „mutující tabulky“. Obecně platí, že spouštěč na úrovni řádku v tabulce A (tj. properties ) nelze dotazovat tabulku A. Tento problém můžete obejít vytvořením balíčku, vytvořením kolekce v tomto balíčku, inicializací kolekce ve spouštěči příkazu before, zapsáním klíčů, které jsou vloženy nebo aktualizovány do kolekce, ve spouštěči na úrovni řádku. a poté iteraci přes prvky kolekce ve spouštěči příkazu after a vydání příslušného DML pro tabulku. To však zahrnuje spoustu pohyblivých kusů a spoustu složitosti (ačkoli složitost je snížena, pokud jste na 11g a můžete místo toho použít složený spouštěč).

Pokud se navíc pokusíte použít spouštěč, narazíte na problémy v prostředí s více uživateli. Pokud uživatel A vloží řádek do jedné relace a uživatel B vloží duplicitní řádek do jiné relace před potvrzením uživatele A, žádný spouštěč relace duplicitní řádek nezjistí. Tento druh problému můžete potenciálně obejít explicitním uzamčením řádku v nadřazené tabulce, aby bylo možné serializovat vložky do tabulky (záměrně zpomalit aplikaci a snížit její škálovatelnost). Omezení by však bylo mnohem efektivnější a praktičtější řešení.

Vše, co bylo řečeno, pokud provádíte pouze jednořádkové vkládání pomocí INSERT ... VALUES syntaxi a omezit se na jednu relaci, váš spouštěč se zdá být funkční

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. SQL - Jak najít nejvyšší číslo ve sloupci?

  2. Psycopg2 nemá rád názvy tabulek, které začínají malým písmenem

  3. count(*) a count(název_sloupce), jaký je rozdíl?

  4. Vraťte řádky, které obsahují alfanumerické znaky v SQLite