创建禁止性约束:
•
加
disable
关键字即可。
SQL> create table t(id int, name char(10));
表已创建。
SQL> desc t
名称
是否为空
?
类型
----------------------------------------- -------- -------------------------
ID NUMBER(38)
NAME CHAR(10)
SQL> alter table t add constraint uq_t_id unique(id) disable;
表已更改。
SQL> insert into t values(0,'aaa');
已创建
1
行。
SQL> insert into t values(0,'aaa');
已创建
1
行。
SQL>
SQL> insert into t values(0,'aaa');
已创建
1
行。
SQL> insert into t values(0,'aaa');
已创建
1
行。
SQL> select * from t;
ID NAME
---------- --------------------------------------------------
0 aaa
0 aaa
0 aaa
0 aaa
启用约束:
SQL> delete from t;
已删除
4
行。
SQL> alter table t enable unique;
alter table t enable unique
*
ERROR
位于第
1
行
:
ORA-00906: missing left parenthesis
SQL> alter table t enable unique(id);
表已更改。
SQL> insert into t values(0,'aaa');
已创建
1
行。
SQL> insert into t values(0,'aaa');
insert into t values(0,'aaa')
*
ERROR
位于第
1
行
:
ORA-00001: unique constraint (LUO.UQ_T_ID) violated
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
BONUS TABLE
CUSTOMERS TABLE
DINGDAN TABLE
ORDERS TABLE
PK_CUST INDEX
T TABLE
UQ_EMP_ID INDEX
UQ_T_ID INDEX
已选择
8
行。
SQL> drop table t;
表已丢弃。
SQL> create table t(id int, name char(10));
表已创建。
SQL> alter table t add constraint pk_t_id primary key(id) disable;
表已更改。
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
BONUS TABLE
CUSTOMERS TABLE
DINGDAN TABLE
ORDERS TABLE
PK_CUST INDEX
T TABLE
UQ_EMP_ID INDEX
已选择
7
行。
SQL> insert into t values(1,'aaa');
已创建
1
行。
SQL> insert into t values(1,'bbb');
已创建
1
行。
SQL> commit;
提交完成。
SQL> select * from t;
ID NAME
---------- --------------------------------------------------
1 aaa
1 bbb
SQL> delete from t where name='bbb';
已删除
1
行。
SQL> commit ;
提交完成。
SQL> alter table t enable primary key; #
启用主键约束可以不用带列名。
表已更改。
SQL> insert into t values(1,'bbb');
insert into t values(1,'bbb')
*
ERROR
位于第
1
行
:
ORA-00001: unique constraint (LUO.PK_T_ID) violated
SQL> insert into t values(2,'bbb');
已创建
1
行。
SQL> commit ;
提交完成。
SQL> select * from t;
ID NAME
---------- --------------------------------------------------
1 aaa
2 bbb
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
BONUS TABLE
CUSTOMERS TABLE
DINGDAN TABLE
ORDERS TABLE
PK_CUST INDEX
PK_T_ID INDEX
T TABLE
UQ_EMP_ID INDEX
已选择
8
行。
SQL> alter table t disable primary key; #
再次禁用。
表已更改。
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
BONUS TABLE
CUSTOMERS TABLE
DINGDAN TABLE
ORDERS TABLE
PK_CUST INDEX
T TABLE
UQ_EMP_ID INDEX
已选择
7
行。
#
索引消失。
删除约束:
Alter table bonus drop constraint ck_bonus;
删除
unique
或主键约束时,如果是被引用为外键的则带上
cascade
参数,删除
unique
约束同时删除了子表的外键约束。
Alter table bonus drop primary key cascade;
实验:
SQL> select constraint_name,status,validated from user_constraints;
CONSTRAINT_NAME STATUS VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763 ENABLED VALIDATED
CK_BONUS ENABLED VALIDATED
CK_BONUS2 ENABLED VALIDATED
UQ_EMP_ID ENABLED VALIDATED
PK_CUST ENABLED VALIDATED
FK_CUST ENABLED VALIDATED
CK_DPTID ENABLED VALIDATED
已选择
7
行。
SQL> alter table bonus drop constraint ck_bonus2;
表已更改。
SQL> select constraint_name,status,validated from user_constraints;
CONSTRAINT_NAME STATUS VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763 ENABLED VALIDATED
CK_BONUS ENABLED VALIDATED
UQ_EMP_ID ENABLED VALIDATED
PK_CUST ENABLED VALIDATED
FK_CUST ENABLED VALIDATED
CK_DPTID ENABLED VALIDATED
已选择
6
行。
SQL> alter table customers drop primary key cascade;
表已更改。
SQL> select constraint_name,status,validated from user_constraints;
CONSTRAINT_NAME STATUS VALIDATED
------------------------------ ---------------- --------------------------
SYS_C002763 ENABLED VALIDATED
CK_BONUS ENABLED VALIDATED
UQ_EMP_ID ENABLED VALIDATED
CK_DPTID ENABLED VALIDATED
约束状态:
图
5
可以启用
(ENABLE)
或禁用
(DISABLE)
完整性约束。如果启用某个约束,则在数据库中输入或更新数据时,就会对数据进行检查。禁止输入不符合约束规则的数据。如果禁用某个约束,则可以在数据库中输入不符合约束规则的数据。完整性约束可处于以下状态之一:
• DISABLE NOVALIDATE
• DISABLE VALIDATE
• ENABLE NOVALIDATE
• ENABLE VALIDATE
DISABLE NOVALIDATE
:不检查处于
DISABLE NOVALIDATE
状态的约束。表中的数据(包括输入或更新的新数据)可以不符合约束所定义的规则。
DISABLE VALIDATE
:当约束处于此状态时,不允许对受约束的列进行任何修改。另外,约束上的索引将被删除并且禁用约束。注:如果约束可延迟,则不删除索引。
ENABLE NOVALIDATE
:如果约束处于此状态,则不能输入违反约束的新数据。但是,表可能包含无效的数据,即数据违反约束。启用处于
NOVALIDATE
状态的约束对正在上载有效
OLTP
数据的数据仓库配置是非常有用的。
ENABLE VALIDATE
:如果约束处于此状态,则不能将违反约束的行插入到表中。但是,禁用该约束时,可以插入此类行。此类行称为该约束的例外。如果约束处于
ENABLE NOVALIDATE
状态,则在禁用约束时输入的数据所引起的违反情况仍然存在。要将约束置于已验证状态,必须更新或删除违反约束的行。
当某一约束由禁用状态更改为
ENABLE VALIDATE
时,将锁定表并对表中的所有数据进行一致性检查。这可能会引起
DML
操作(如等待数据加载),因此,建议先从禁用状态转为
ENABLE NOVALIDATE
,然后再转为
ENABLE VALIDATE
。
这些状态之间的转换须符合以下规则:
•
除非指定
NOVALIDATE
,否则
ENABLE
表示
VALIDATE
。
•
除非指定
VALIDATE
,否则
DISABLE
表示
NOVALIDATE
。
• VALIDATE
和
NOVALIDATE
没有缺省的
ENABLE
和
DISABLE
状态。
•
当唯一键或主键从
DISABLE
状态转为
ENABLE
状态且没有现有索引时,将自动创建唯一索引。(如果索引可延迟,则将存在异常。)与此类似,当唯一键或主键从
ENABLE
转为
DISABLE
且是使用唯一索引启用时,则删除该唯一索引。
•
当任何约束从
NOVALIDATE
状态转为
VALIDATE
状态时,必须检查所有的数据。但是,从
VALIDATE
转为
NOVALIDATE
时,将忽略数据已经过检查这一事实。
•
将单个约束从
ENABLE NOVALIDATE
状态转为
ENABLE VALIDATE
状态时,并不禁止使用读取、写入或其它
DDL
语句。
SQL> select constraint_name,table_name,status,validated from user_constraints;
CONSTRAINT_NAME TABLE_NAME STATUS VALIDATED
--------------- -------------------- ---------------- -------------------------
CK_BONUS BONUS ENABLED VALIDATED
UQ_EMP_ID BONUS ENABLED VALIDATED
SQL> desc t
名称
是否为空
?
类型
----------------------------------------- -------- ---------------------------
ID NUMBER(38)
NAME CHAR(10)
DPT_ID NUMBER(38)
SQL> alter table t add constraint ck_dptid check(dpt_id>=10) disable;
表已更改。
SQL> insert into t values(1,'aaa ',1);
已创建
1
行。
SQL> insert into t values(2,'bbb',2);
已创建
1
行。
SQL> insert into t values(3,'ccc',3);
已创建
1
行。
SQL> commit;
提交完成。
SQL> select * from t;
ID NAME DPT_ID
---------- -------------------------------------------------- ----------
1 aaa 1
2 bbb 2
3 ccc 3
SQL> alter table t enable novalidate constraint ck_dptid;
表已更改。
SQL> select constraint_name,table_name,status,validated from user_constraints;
CONSTRAINT_NAME TABLE_NAME STATUS VALIDATED
--------------- -------------------- ---------------- -------------------------
CK_BONUS BONUS ENABLED VALIDATED
UQ_EMP_ID BONUS ENABLED VALIDATED
CK_DPTID T ENABLED NOT VALIDATED
SQL> insert into t values(3,'ddd',4);
insert into t values(3,'ddd',4)
*
ERROR
位于第
1
行
:
ORA-02290: check constraint (LUO.CK_DPTID) violated
SQL> insert into t values(3,'ddd',11);
已创建
1
行。
#
启用
enable novalidate
状态成功。
SQL> alter table t add constraint pk_t_id primary key(id) disable;
表已更改。
SQL> select constraint_name,table_name,status,validated from user_constrai
CONSTRAINT_NAME TABLE_NAME STATUS VALIDATED
--------------- -------------------- ---------------- --------------------
CK_BONUS BONUS ENABLED VALIDATED
UQ_EMP_ID BONUS ENABLED VALIDATED
CK_DPTID T ENABLED NOT VALIDATED
PK_T_ID T DISABLED NOT VALIDATED
SQL> select * from t;
ID NAME DPT_ID
---------- -------------------------------------------------- ----------
1 aaa 1
2 bbb 2
3 ccc 3
3 ddd 11
SQL> alter table t enable novalidate primary key;
alter table t enable novalidate primary key
*
ERROR
位于第
1
行
:
ORA-02437: cannot validate (LUO.PK_T_ID) - primary key violated
#
报错的原因是因为启用主键约束后会创建一个非唯一性索引,但表中有重复值,索引创建不成功。解决方法可以删除表中主键列的重复值,或用下面的方法。
SQL> create index t_id on t(id);
索引已创建。
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
BONUS TABLE
CUSTOMERS TABLE
ORDERS TABLE
T TABLE
T_ID INDEX
UQ_EMP_ID INDEX
已选择
6
行。
SQL> alter table t enable novalidate primary key;
表已更改。
SQL> insert into t values(2,'eee',12);
insert into t values(2,'eee',12)
*
ERROR
位于第
1
行
:
ORA-00001: unique constraint (LUO.PK_T_ID) violated
SQL> insert into t values(4,'eee',12);
已创建
1
行。
当有大量数据处理时,一致性约束同索引一样会降低数据库性能。因此,可以按以下方法提高性能。
图
6
约束检查时间:
图
7
在约束定义完成以后,
nondeferred
与
deferred
不能相互转变。
SET CONSTRAINTS
语句用于将特定事务处理的约束设置为
DEFERRED
或
IMMEDIATE
。
可以使用此语句设置约束名称列表或约束的模式。
SET CONSTRAINTS
模式将一直持续到事务处理完成或者另一个
SET CONSTRAINTS
语句重置模式。
SET CONSTRAINTS
语句不允许在触发器内部使用。
ALTER SESSION
语句还包含将约束设置为
IMMEDIATE
或
DEFERRED
的子句
SET CONSTRAINTS
。此命令缺省为设置所有
(ALL)
可延迟的约束(不能指定约束名称列表)。
ALTER SESSION SET CONSTRAINTS
语句仅适用于当前的会话。
ALTER SESSION
SET CONSTRAINT[S] =
{IMMEDIATE|DEFERRED|DEFAULT}
SET CONSTRAINT | CONSTRAINTS
{constraint |ALL }
{IMMEDIATE|DEFERRED}
实验:
SQL> create table t(id int,name char(10),dpt_id int);
表已创建。
SQL> desc t;
名称
是否为空
?
类型
----------------------------------------- -------- ----------------------
ID NUMBER(38)
NAME CHAR(10)
DPT_ID NUMBER(38)
SQL> alter table t add constraint pk_t_id primary key(id);
表已更改。
SQL> select index_name,uniqueness from user_indexes;
INDEX_NAME UNIQUENESS
------------------------------------------------------------ -------------
PK_T_ID UNIQUE
SQL> alter table t drop primary key;
表已更改。
SQL> alter table t add constraint pk_t_id primary key(id) deferrable;
表已更改。
SQL> select index_name,uniqueness from user_indexes;
INDEX_NAME UNIQUENESS
------------------------------------------------------------ -------------
PK_T_ID NONUNIQUE
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
PK_T_ID INDEX
T TABLE
已选择
6
行。
SQL> alter table t disable primary key;
表已更改。
SQL> select object_name,object_type from user_objects;
OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------------
PK_T_ID INDEX
T TABLE
已选择
6
行。
#
如果索引是非唯一性索引,在
disable
主键约束时,不会删除相应索引。
SQL> insert into t values(1,'aaa',1);
已创建
1
行。
SQL> insert into t values(1,'aaa',1);
已创建
1
行。
SQL> commit;
提交完成。
SQL> select constraint_name,table_name,status,validated from user_constrai
CONSTRAINT_NAME TABLE_NAME STATUS VALIDATED
--------------- -------------------- ---------------- --------------------
PK_T_ID T DISABLED NOT VALIDATED
SQL> alter table t enable novalidate primary key;
表已更改。
SQL> select constraint_name,table_name,status,validated from user_constrai
CONSTRAINT_NAME TABLE_NAME STATUS VALIDATED
--------------- -------------------- ---------------- --------------------
PK_T_ID T ENABLED NOT VALIDATED
SQL> insert into t values(1,'aaa',1);
insert into t values(1,'aaa',1)
*
ERROR
位于第
1
行
:
ORA-00001: unique constraint (LUO.PK_T_ID) violated
SQL> select * from t;
ID NAME DPT_ID
---------- -------------------------------------------------- ----------
1 aaa 1
1 aaa 1
SQL> set constraints all deferred;
约束条件已设置。
SQL> insert into t values(1,'aaa',1);
已创建
1
行。
SQL> insert into t values(1,'aaa',1);
已创建
1
行。
SQL> insert into t values(1,'aaa',1);
已创建
1
行。
SQL> select * from t;
ID NAME DPT_ID
---------- -------------------------------------------------- ----------
1 aaa 1
1 aaa 1
1 aaa 1
1 aaa 1
1 aaa 1
SQL> commit;
commit
*
ERROR
位于第
1
行
:
ORA-02091: transaction rolled back
ORA-00001: unique constraint (LUO.PK_T_ID) violated
本文转自 d185740815 51CTO博客,原文链接:http://blog.51cto.com/luotaoyang/293804,如需转载请自行联系原作者