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

Více omezení v tabulce:Jak získat všechna porušení?

Neexistuje žádný přímý způsob, jak nahlásit všechna možná porušení omezení. Protože když Oracle narazí na první porušení omezení, není možné další vyhodnocení, příkaz selže, pokud toto omezení není odloženo nebo log errors klauzule byla zahrnuta do prohlášení DML. Ale je třeba poznamenat, že log errors klauzule nebude schopna zachytit všechna možná porušení omezení, pouze zaznamená první z nich.

Jedním z možných způsobů je:

  1. vytvářejte exceptions stůl. To lze provést spuštěním ora_home/rdbms/admin/utlexpt.sql skript. Struktura tabulky je docela jednoduchá;
  2. zakázat všechna omezení tabulky;
  3. provádět DML;
  4. povolte všechna omezení s exceptions into <<exception table name>> doložka. Pokud jste spustili utlexpt.sql skript, název výjimek tabulky, které se mají uložit, bude exceptions .

Testovací tabulka:

create table t1(
  col1 number not null,
  col2 number not null,
  col3 number not null,
  col4 number not null
);

Zkuste provést insert prohlášení:

insert into t1(col1, col2, col3, col4)
  values(1, null, 2, null);

Error report -
SQL Error: ORA-01400: cannot insert NULL into ("HR"."T1"."COL2")

Zakázat všechna omezení tabulky:

alter table T1 disable constraint SYS_C009951;     
alter table T1 disable constraint SYS_C009950;     
alter table T1 disable constraint SYS_C009953;     
alter table T1 disable constraint SYS_C009952; 

Pokuste se provést dříve neúspěšné insert znovu prohlášení:

insert into t1(col1, col2, col3, col4)
  values(1, null, 2, null);

1 rows inserted.

commit;

Nyní povolte omezení tabulky a uložte výjimky, pokud nějaké existují, do exceptions tabulka:

alter table T1 enable constraint SYS_C009951 exceptions into exceptions; 
alter table T1 enable constraint SYS_C009950 exceptions into exceptions; 
alter table T1 enable constraint SYS_C009953 exceptions into exceptions; 
alter table T1 enable constraint SYS_C009952 exceptions into exceptions; 

Zkontrolujte exceptions tabulka:

column row_id     format a30;
column owner      format a7;
column table_name format a10;
column constraint format a12;

select *
  from exceptions 

ROW_ID                         OWNER   TABLE_NAME CONSTRAINT 
------------------------------ ------- -------    ------------
AAAWmUAAJAAAF6WAAA             HR      T1         SYS_C009951  
AAAWmUAAJAAAF6WAAA             HR      T1         SYS_C009953

Byla porušena dvě omezení. Chcete-li zjistit názvy sloupců, jednoduše se podívejte na user_cons_columns zobrazení datového slovníku:

column table_name   format a10;
column column_name  format a7;
column row_id       format a20;

select e.table_name
     , t.COLUMN_NAME
     , e.ROW_ID
  from user_cons_columns t
  join exceptions e
    on (e.constraint = t.constraint_name)


TABLE_NAME COLUMN_NAME ROW_ID             
---------- ----------  --------------------
T1         COL2        AAAWmUAAJAAAF6WAAA   
T1         COL4        AAAWmUAAJAAAF6WAAA

Výše uvedený dotaz nám poskytuje názvy sloupců a řádky problematických záznamů. S rowids po ruce by neměl být problém najít ty záznamy, které způsobují porušení omezení, opravit je a znovu povolit omezení.

Zde je skript, který byl použit ke generování alter table příkazy pro aktivaci a deaktivaci omezení:

column cons_disable format a50
column cons_enable format a72

select 'alter table ' || t.table_name || ' disable constraint '|| 
        t.constraint_name || ';' as cons_disable
     , 'alter table ' || t.table_name || ' enable constraint '|| 
        t.constraint_name || ' exceptions into exceptions;' as cons_enable
  from user_constraints t
where t.table_name = 'T1'
order by t.constraint_type


  1. Více databází v dockeru a docker-compose

  2. Získejte více hodnot v SQL Server Cursor

  3. Spojte hodnotu druhého sloupce, pokud je hodnota prvního sloupce stejná

  4. Jak funguje SQLite Char()