sql – 表中的多个约束:如何获取所有违规?

前端之家收集整理的这篇文章主要介绍了sql – 表中的多个约束:如何获取所有违规?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在Oracle中有一个表,有几个限制.当我插入一个新的记录,并不是所有的约束是有效的,那么Oracle只会引发“第一个”错误.如何获得所有违反我记录的行为?
  1. CREATE TABLE A_TABLE_TEST (
  2. COL_1 NUMBER NOT NULL,COL_2 NUMBER NOT NULL,COL_3 NUMBER NOT NULL,COL_4 NUMBER NOT NULL
  3. );
  4.  
  5. INSERT INTO A_TABLE_TEST values (1,null,2);
  6.  
  7. ORA-01400: cannot insert NULL into ("USER_4_8483C"."A_TABLE_TEST"."COL_2")

我想得到这样的东西:

  1. Column COL_2: cannot insert NULL
  2. Column COL_3: cannot insert NULL
  3.  
  4. This would be also sufficient:
  5. Column COL_2: not valid
  6. Column COL_3: not valid

当然我可以写一个触发器并单独检查每个列,但我喜欢限制而不是触发器,它们更容易维护,不需要手动编写代码.

任何想法?

解决方法

没有直接的方式报告所有可能的约束违规.因为当Oracle在第一次违反约束时绊倒时,不能再进行评估,否则语句失败,除非该约束被延迟,否则日志错误子句已被包含在DML语句中.但是应该注意的是,log errors子句将无法捕获所有可能的约束违例,只记录第一个.

作为可能的方法之一是:

>创建异常表.可以通过执行ora_home / rdbms / admin / utlexpt.sql脚本来完成.桌子的结构很简单;
>禁用所有表约束;
>执行DML;
>将具有异常的所有约束启用到<< exception table name>>>条款.如果你执行了utlexpt.sql脚本,那么将要存储的表的异常名称将是异常.

测试表:

  1. create table t1(
  2. col1 number not null,col2 number not null,col3 number not null,col4 number not null
  3. );

尝试执行一个insert语句:

  1. insert into t1(col1,col2,col3,col4)
  2. values(1,2,null);
  3.  
  4. Error report -
  5. sql Error: ORA-01400: cannot insert NULL into ("HR"."T1"."COL2")

禁用所有表的约束:

  1. alter table T1 disable constraint SYS_C009951;
  2. alter table T1 disable constraint SYS_C009950;
  3. alter table T1 disable constraint SYS_C009953;
  4. alter table T1 disable constraint SYS_C009952;

尝试再次执行以前失败的insert语句:

  1. insert into t1(col1,null);
  2.  
  3. 1 rows inserted.
  4.  
  5. commit;

现在,在异常表中启用表的约束并存储异常(如果有):

  1. alter table T1 enable constraint SYS_C009951 exceptions into exceptions;
  2. alter table T1 enable constraint SYS_C009950 exceptions into exceptions;
  3. alter table T1 enable constraint SYS_C009953 exceptions into exceptions;
  4. alter table T1 enable constraint SYS_C009952 exceptions into exceptions;

检查例外表:

  1. column row_id format a30;
  2. column owner format a7;
  3. column table_name format a10;
  4. column constraint format a12;
  5.  
  6. select *
  7. from exceptions
  8.  
  9. ROW_ID OWNER TABLE_NAME CONSTRAINT
  10. ------------------------------ ------- ------- ------------
  11. AAAWmUAAJAAAF6WAAA HR T1 SYS_C009951
  12. AAAWmUAAJAAAF6WAAA HR T1 SYS_C009953

两个限制已被违反.要查找列名,只需参考user_cons_columns数据字典视图:

  1. column table_name format a10;
  2. column column_name format a7;
  3. column row_id format a20;
  4.  
  5. select e.table_name,t.COLUMN_NAME,e.ROW_ID
  6. from user_cons_columns t
  7. join exceptions e
  8. on (e.constraint = t.constraint_name)
  9.  
  10.  
  11. TABLE_NAME COLUMN_NAME ROW_ID
  12. ---------- ---------- --------------------
  13. T1 COL2 AAAWmUAAJAAAF6WAAA
  14. T1 COL4 AAAWmUAAJAAAF6WAAA

上述查询给出了列名称和有问题记录的rowid.有了rowid在手,找到那些引起约束违规的记录,修复它们,再次重新启用约束应该没有问题.

以下是用于生成用于启用和禁用约束的alter table语句的脚本:

  1. column cons_disable format a50
  2. column cons_enable format a72
  3.  
  4. select 'alter table ' || t.table_name || ' disable constraint '||
  5. t.constraint_name || ';' as cons_disable,'alter table ' || t.table_name || ' enable constraint '||
  6. t.constraint_name || ' exceptions into exceptions;' as cons_enable
  7. from user_constraints t
  8. where t.table_name = 'T1'
  9. order by t.constraint_type

猜你在找的MsSQL相关文章