sql >> Databasteknik >  >> RDS >> Oracle

Flera begränsningar i tabellen:Hur får man alla överträdelser?

Det finns inget enkelt sätt att rapportera alla möjliga överträdelser av begränsningar. För när Oracle stöter på första överträdelse av en begränsning är ingen ytterligare utvärdering möjlig, uttalandet misslyckas, om inte den begränsningen skjuts upp en eller loggfel klausul har inkluderats i DML-utlåtandet. Men det bör noteras att loggfel klausul kommer inte att kunna fånga alla möjliga överträdelser av begränsningar, bara registrerar den första.

Som ett av de möjliga sätten är att:

  1. skapa undantag tabell. Det kan göras genom att köra ora_home/rdbms/admin/utlexpt.sql manus. Tabellens struktur är ganska enkel;
  2. inaktivera alla tabellbegränsningar;
  3. kör DML:er;
  4. aktivera alla begränsningar med undantag i <> klausul. Om du körde utlexpt.sql skript, namnet på tabellundantagen som kommer att lagras skulle vara undantag .

Testtabell:

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

Försök att köra en insert uttalande:

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")

Inaktivera alla tabellens begränsningar:

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; 

Försök att köra den tidigare misslyckade insert uttalande igen:

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

1 rows inserted.

commit;

Aktivera nu tabellens begränsningar och lagra undantag, om det finns några, i undantag tabell:

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; 

Kontrollera undantagen tabell:

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

Två begränsningar har överträtts. För att ta reda på kolumnnamn hänvisar du helt enkelt till user_cons_columns dataordbokvy:

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

Ovanstående fråga ger oss kolumnnamn och rader med problematiska poster. Om du har radider till hands borde det inte vara några problem att hitta de poster som orsakar överträdelse av begränsningar, åtgärda dem och återaktivera begränsningar igen.

Här är skriptet som har använts för att generera ändringstabell uttalanden för att aktivera och inaktivera begränsningar:

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. Radnummer per grupp i mysql

  2. Prisma, hur man rensar databasen

  3. Row Goals, Del 4:Anti Join Anti Pattern

  4. Webbseminarium:Spårning av frågeförlopp i SQL Server