Oracle约束的状态及验证机制

一、Oracle约束的状态

Oracle完整性约束的状态有4种,分别是ENABLE、DISABLE、VALIDATE、NOVALIDATE。

  • ENABLE          表示Oracle将检查要插入或更新的数据库中的数据是否符合约束;
  • DISABLE         表示表中可以存放违反约束的行;
  • VALIDATE       表示数据库验证表中的已存在数据是否符合约束;
  • NOVALIDATE  表示数据库不验证表中已存在数据是否符合约束。

Oracle默认约束状态为ENABLE、VALIDATE。

下面看Oracle官方给出的汇总:

Modified Data Existing Data Summary

ENABLE


VALIDATE


Existing and future data must obey the constraint. An attempt to apply a new constraint to a populated table results in an error if existing rows violate the constraint.


ENABLE


NOVALIDATE


The database checks the constraint, but it need not be true for all rows. Thus, existing rows can violate the constraint, but new or modified rows must conform to the rules.


DISABLE


VALIDATE


The database disables the constraint, drops its index, and prevents modification of the constrained columns.


DISABLE


NOVALIDATE


The constraint is not checked and is not necessarily true.

下面使用实例测试各状态:

创建测试表

[email protected]>create table t1 (id number,name varchar2(10),address varchar2(10));

Table created.

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>commit;

Commit complete.

1、测试ENABLE、VALIDATE状态

[email protected]>alter table t1 add constraint t1_uk unique(id);
alter table t1 add constraint t1_uk unique(id)
                              *
ERROR at line 1:
ORA-02299: cannot validate (ZX.T1_UK) - duplicate keys found

因为id列中有重复值,此时创建约束t1_uk的状态为ENABLE、VALIDATE会验证表中已存在的数据,所以创建约束不成功。删除表中的重复数据再次创建约束即可成功。

[email protected]>delete from t1 where id=1 and name=‘zq‘;

1 row deleted.

[email protected]>commit;

Commit complete.

[email protected]>alter table t1 add constraint t1_uk unique(id);

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U NOT DEFERRABLE ENABLED	VALIDATED

创建完成后再次插入id=1的数据即会报错,说明约束状态为ENABLE

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);
insert into t1 values(1,‘zq‘,‘jx‘)
*
ERROR at line 1:
ORA-00001: unique constraint (ZX.T1_UK) violated

2、测试ENABLE、DISABLED状态

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd
	 1 zq	      jx

[email protected]>alter table t1 add constraint t1_uk unique(id) enable novalidate;
alter table t1 add constraint t1_uk unique(id) enable novalidate
                              *
ERROR at line 1:
ORA-02299: cannot validate (ZX.T1_UK) - duplicate keys found

直接创建unique约束报错,因为有重复值。但先在id列上创建索引,然后创建unique约束即可成功。

[email protected]>create index idx_t_id on t1(id);

Index created.

[email protected]>alter table t1 add constraint t1_uk unique(id) using index idx_t_id enable novalidate;

Table altered.

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd
	 1 zq	      jx

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U NOT DEFERRABLE ENABLED	NOT VALIDATED

原表中的id列中有重复值,还是可以创建unique约束,因为状态指定为NOVALIDATE,不验证表中已有的数据。另外因为状态为ENABLE,再次插入重复值报错:

[email protected]>insert into t1 values(2,‘yc‘,‘bj‘);
insert into t1 values(2,‘yc‘,‘bj‘)
*
ERROR at line 1:
ORA-00001: unique constraint (ZX.T1_UK) violated

3、测试DISABLE、VALIDATE状态

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd

[email protected]>alter table t1 add constraint t1_uk unique(id) using index idx_t_id disable validate;

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U NOT DEFERRABLE DISABLED VALIDATED

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);
insert into t1 values(1,‘zq‘,‘jx‘)
*
ERROR at line 1:
ORA-25128: No insert/update/delete on table with constraint (ZX.T1_UK) disabled and validated

DISABLE、VALIDATE状态下,不允许做增删改操作。

4、测试DISABLE、NOVALIDATE状态

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd
	 1 zq	      jx

[email protected]>alter table t1 add constraint t1_uk unique(id) using index idx_t_id disable novalidate;

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U NOT DEFERRABLE DISABLED NOT VALIDATED

[email protected]>insert into t1 values(2,‘yc‘,‘bj‘);

1 row created.

[email protected]>commit;

Commit complete.

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd
	 1 zq	      jx
	 2 yc	      bj

约束状态为DISABLE、NOVALIDATE,对新数据和老数据都不做验证。

二、验证机制

1. 两种验证时机.

Oracle的constraints(约束) 根据验证时机可以分成两种.

case 1.  在每一句insert statement 执行时就会马上验证, 如果约束验证失败,  则这句sql statement 会执行失败.

case 2.   执行insert statements 时不会验证,   在commit的时候验证, 如果验证失败, 则整个Transaction 回滚.

2.constraints的分类

对应地,  oracle 的 constraints 也可以分成两大类.

一种是not deferrable (不可以延时的) . 这种情况下只能执行 case1 的验证时机(即时验证)

另一种是 deferrable (可以设置成延时的).   这种情况下可以执行 case 1 或 case2 的验证时机. 但需要设置.

对于第二种defferable 分类, 还可以分成两小类.

一种是 initially immediate ,  意思时默认情况下执行case 1.

另一种是initially deferred,  意思是默认情况下执行case2.

也就是可以分成三种,如下图:

2.1、not deferrable

这种最常见也最简单.  如果在增加1个constraint 时不指定验证时机属性. 默认情况下就会被设为not deferrable.既然constraint 是不可以延时验证的,  所以也不用设定它的初始属性(实际上就是initially immediate)。

清空上面的t1表,并创建一个unique约束

[email protected]>truncate table t1;

Table truncated.

[email protected]>select * from t1;

no rows selected

[email protected]>alter table t1 add constraint t1_uk unique (id) not deferrable;

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U NOT DEFERRABLE ENABLED	VALIDATED

约束为NOT DEFERRABLE状态,插入测试数据查看状态:

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);
insert into t1 values(1,‘zq‘,‘jx‘)
*
ERROR at line 1:
ORA-00001: unique constraint (ZX.T1_UK) violated

[email protected]>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd

插入第三条数据时因为有重复数据,直接报错,说明验证时机为case1:即时验证,但不会回滚之前插入的结果。

2.2、 deferrable、initially immediate状态

[email protected]>alter table t1 drop constraint t1_uk;

Table altered.

[email protected]>alter table t1 add constraint t1_uk unique (id) deferrable initially immediate;

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U DEFERRABLE     ENABLED	VALIDATED

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);
insert into t1 values(1,‘zq‘,‘jx‘)
*
ERROR at line 1:
ORA-00001: unique constraint (ZX.T1_UK) violated

[email protected]A11G>select * from t1;

	ID NAME       ADDRESS
---------- ---------- ----------
	 1 zx	      hb
	 2 wl	      sd

插入第三条数据时报错因为有重复值,说明验证时机为case1:即时验证,这与前一种状态一样。那为什么还要设置这样一种状态呢?我们来执行下面的语句:

[email protected]>set constraint t1_uk deferred;

Constraint set.

上面的语句并没有改变这个constraint的任何属性, 只不过是切换为另一种模式

也就是说初始是immediate模式的,   执行上面的语句后就临时变成deferred模式了.

再次执行前面的插入语句:

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);

1 row created.

第三条也能插入进去,下面尝试commit:

[email protected]>commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-00001: unique constraint (ZX.T1_UK) violated

[email protected]>select * from t1;

no rows selected

commit时报错,查询t1表,没有任何数据,说明回滚了整个事务。即case2:延迟验证。此时再次执行上面的三次插入操作:

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);
insert into t1 values(1,‘zq‘,‘jx‘)
*
ERROR at line 1:
ORA-00001: unique constraint (ZX.T1_UK) violated

从上面结果可以看出,插入第三行时又报错,说明上面的set constraint语句的作用范围只有当前的一个事务。事务结束后即约束状态即回到原模式。

2.3、deferrable、initially deferred

有了上面的第二个实验就可以很容易的理解这一状态了。

[email protected]>alter table t1 drop constraint t1_uk;

Table altered.

[email protected]>alter table t1 add constraint t1_uk unique (id) deferrable initially deferred;

Table altered.

[email protected]>select table_name,constraint_name,constraint_type,deferrable,status,validated from user_constraints where table_name=‘T1‘;

TABLE_NAME		       CONSTRAINT_NAME		      C DEFERRABLE     STATUS	VALIDATED
------------------------------ ------------------------------ - -------------- -------- -------------
T1			       T1_UK			      U DEFERRABLE     ENABLED	VALIDATED

[email protected]>insert into t1 values(1,‘zx‘,‘hb‘);

1 row created.

[email protected]>insert into t1 values(2,‘wl‘,‘sd‘);

1 row created.

[email protected]>insert into t1 values(1,‘zq‘,‘jx‘);

1 row created.

[email protected]>commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-00001: unique constraint (ZX.T1_UK) violated

[email protected]>select * from t1;

no rows selected

参考:http://blog.csdn.net/nvd11/article/details/12654691

http://docs.oracle.com/cd/E11882_01/server.112/e40540/datainte.htm#CNCPT33337

时间: 2024-10-05 07:57:29

Oracle约束的状态及验证机制的相关文章

Oracle数据库的三种验证机制

关于超级管理员登陆不需要密码因为: 数据库的三种验证机制: 操作系统验证(具有sysdba和sysopera的用户) 密码文件验证(具有sysdba和sysopera的用户) 数据库验证(普通用户) 因为不需要密码是不安全的,所以一般在计算机管理中的用户组ora_dba把Administrator删除,删除之后就要输入密码了. 启动监听:lsnrctl start 查看监听:lsnrctl status 停止监听:lsnrctl stop 1.oracle 数据服务器包括:实例进程和数据库:  

Oracle约束状态

第一: oracle约束的4种状态: disable novalidate 既不会约束新增数据也不会验证已有数据,等同于disable enable novalidate 约束新增数据但不会验证已有数据 disable validate 约束新增数据但不会验证已有数据,启用后禁止DML enable validate 约束新增数据并验证已有数据,等同于enable 测试: --1.创建一个实验表 CREATE TABLE check_test AS SELECT * FROM scott.emp

Oracle基础学习2--Oracle登录与三种验证机制

首先,Oracle安装完毕有三个默认用户 ?  Sys:数据库对象的拥有者.权限最高.password在安装的时候(口令管理)能够改变 ?  System:数据库管理员,password为manager ?  Scott:一个普通用户,password为tiger 再看连接Oracle的三种验证机制 ?  操作系统验证(具体解释见以下) ?  password文件验证 ?  数据库验证 注:前两者适用于系统用户,比方:Sys.System等:最后一个适用于普通用户.比方:Scott. 再看Ora

[Oracle]约束(constraint)

(一)约束的概念 在Oracle中,可以通过设置约束来防止无效数据进入表中.Oracle一共有5种约束: 主键约束(primary key) 外键约束(foreign key) 唯一性约束(unique) 非空约束(not null) 检查约束(check) (1)主键约束 --主键约束可以定义在一列或多列上,值具有唯一性.非空性: --在一个表上只能定义一个主键约束: --Oracle会自定在主键约束的列上创建唯一性索引,可以指定唯一性索引的位置及存储参数. (2)外键约束 --外键约束列的取

ORACLE【2】:锁机制及解锁

1. 锁的基本知识 根据要保护的对象不同,oracle的数据锁可以分成以下几类:DML锁,(data locks)数据锁,用于保护数据的完整性:DDL锁(dictionary locks),用于保护数据库内部结构,如表,索引等结构定义:内部锁和闩(internal locks and latcheds),保护数据库内部结构. 我们通常遇到的都是DML锁,DML锁在通常状态下都是用于保证并发情况下的数据完整性.在oracle中,主要包含有TM锁和TX锁,其中TM锁称为表级锁,TX锁称行级锁或事物锁

深入tomcat验证机制

背景 <<Head First Servlets & JSP>>安全一章介绍了tomcat内建的验证机制. 首先介绍术语realm. As far as theservlet spec is concerned, arealm is a place where authentication information is stored. When you'retesting your application in Tomcat, you can use a file call

Linux用户安全及Linux PAM验证机制

一.Linux身份验证 1.用户与系统管理员     >用户分为系统管理员与普通管理用户两大类.            >每个用户在系统中都有唯一的用户名,是用户使用系统的凭证.     >系统管理员(System Manager) 又称之为超级用户,账号为"root",也叫根用户,拥有系统操作最高行使权.         >在系统中具有最高权限,主要负责系统管理工作.     >普通用户的账号可以随意取,通常的要求是不能以数字和下划线作为第一个字符.  

basic用户验证机制

basic用户验证机制 1,修改配置文件 vim /etc/httpd/conf.d/test.conf 6 <directory /var/www/html/admin/> 7 authtype basic 8 AuthName "admin Page" 9 AuthUserFile "/etc/httpd/conf.d/.httpuser" 10 Require user tom alice 11 </directory> 2,创建用户账

定制Asp.NET 5 MVC内建身份验证机制 - 基于自建SQL Server用户/角色数据表的表单身份验证

背景 在需要进行表单认证的Asp.NET 5 MVC项目被创建后,往往需要根据项目的实际需求做一系列的工作对MVC 5内建的身份验证机制(Asp.NET Identity)进行扩展和定制: Asp.NET内建的身份验证机制会使用Local DB(本地数据库)读写用户相关的信息,而在数据库驱动的项目中,管理业务信息的数据库通常是特定的数据库环境,比如远程SQL Server数据库实例或Access数据库等等,业务数据库中保存着一系列针对业务需求的数据表,因此需要定制MVC 5内建身份验证,使其操作