ORACLE约束(constraint):对象的强制规定

ORACLE约束(constraint):对象的强制规定

5种约束:
NOT NULL     非空 NN
UNIQUE       唯一 UK
PRIMARY KEY  主键 PK
FOREIGN KEY  外键 FK
CHECK        条件 CK

约束创建:
1)创建对象时定义
2) 创建对象后定义
3) 约束有名字:默认:SYS_C0, 系统推荐:表名_列名_约束类型

create table scott.tab
drop table scott.me_stu purge;
create table scott.me_stu(
id    varchar2(20) constraints stu_id_pk  primary key,
nam   varchar2(32) constraints stu_nam_uk unique,
age   number(10)   constraints stu_sal_ck check(age>0),
notes varchar2(32) constraints stu_not_nn not null
) compress nologging;

drop table scott.me_stu purge;
create table scott.me_stu(
id    varchar2(20),
nam   varchar2(32),
age   number(10) ,
notes varchar2(64),
constraints stu_id_pk   primary key(id),
constraints stu_nam_uk  unique(nam),
constraints stu_sal_ck  check(age>0),
constraints stu_notes_nn check(notes is not null)
) compress nologging;
alter table scott.me_stu move compress;

--外键
--参照完整性约束
--限制(Restrict)。不允许进行修改或删除操作。若修改或删除主表的主键时,如果子表中存在子记录,系统将产生一个错误提示。这是缺省的参照完整性设置。
--置空(Set Null)。如果外键列允许为空,若修改或删除主表的主键时,把子表中参照的外键列设置为空值(NULL)。
--置为缺省(Set Default)。如果指定了缺省值,若修改或删除主表的主键时,把子表中参照的外键设置为缺省值(Default)。
--级联(Cascade)。把主表中主键修改为一个新的值时,相应修改子表中外键的值;或者删除主表中主键的记录时,要相应删除子表中外键的记录。
drop table scott.me_score purge;
create table scott.me_score (
sid    varchar2(20) constraint score_sid_fk references scott.me_stu(id),--constraint score_sid_fk references scott.me_stu(id) on delete cascade,
cid    varchar2(20),
score  number(10,2)
) nologging;

drop table scott.me_score purge;
create table scott.me_score (
sid    varchar2(20),
cid    varchar2(20),
score  number(10,2),
--constraint score_sid_fk foreign key(sid) references scott.me_stu(id)
  constraint score_sid_fk foreign key(sid) references scott.me_stu(id) on delete cascade
) nologging;

--查询约束
select * from dba_constraints  where table_name like '%me_stu%';
select * from dba_cons_columns where table_name like '%me_stu%';

--删除约束
alter table scott.me_stu   drop constraints stu_nam_uk;
alter table scott.me_score drop constraints score_sid_fk;

--添加约束
alter table scott.me_stu modify(nam   varchar2(32) constraint stu_nam_nn unique);
alter table scott.me_stu modify(notes varchar2(32) constraint stu_not_nn not null);
alter table scott.me_stu   add constraint stu_nam_uk unique(nam);
alter table scott.me_score add constraint score_sid_fk foreign key(sid) references scott.me_stu(id) on delete cascade;

--外键对DML影响
INSERT:
1)子表对父表无影响
2)插入子表外键时,父表必须存在
DELETE:
1)对子表DELETE操作对父表无影响
2)对父表DELETE操作须先对子表删除
UPDATE:
1)对父表和子表都有影响
2)对父表如果子表引用则不能更新
3)对子表UPDATE操作时,外键在父表必须存在

--外键对DDL影响
1)对子表没影响,对父表如果子表引用则不能删除

--为了消除影响可以在建立约束时添加子句:
on delete set null 主表删除时,子表置空
on delete cascade  主表删除时,子表级联删除

--禁用与启用约束
alter table scott.me_score disable constraint score_sid_fk;
alter table scott.me_score enable  constraint score_sid_fk;

约束(constraint)状态:
ENABLED/DISABLED
VALIDATED/NOVALIDATED
DEFERRABLE/NON-DEFERRABLE
DEFERRED/IMMEDIATE
RELY/NORELY

1)DEFERRABLE/NON-DEFERRABLE,DEFERRED/IMMEDIATE
deferrable:     constraint如果被定义成deferrable那么constraints可以在deferred和imediate两种状态相互转换
not deferrable: constraint默认是not deferrable,同initially immediate,不能在deferred和imediate两种状态相互转换
deferred:       意味着constraint将被延迟即在transaction过程中使constraint失效,等到如果transaction commit时transaction会变成immediate
immediate:      意味着constraint在transaction过程中使constraint一直有效
deferrable initially immediate: 允许将constraint再改为initially deferred
deferrable initially deferred:  允许将constraint再改为initially immediate
drop table scott.test purge;
create table scott.test
(    x number constraint check_x check (x > 0) deferrable initially immediate,
   y number constraint check_y check (y > 0) deferrable initially deferred
)nologging;

alter table scott.test add constraint check_x (x > 0) deferrable initially immediate;
alter table scott.test add constraint check_y (y > 0) deferrable initially deferred;
insert into scott.test values ( 1,1 );
commit;

--initially immediate:在transaction过程中使constraint一直有效
insert into scott.test values (-1,1 );
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CHECK_X) violated

--转换initially immediate=>deferred
set constraint scott.check_x deferred;
insert into scott.test values (-1,1 );
1 row created.
commit;
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint (SCOTT.CHECK_X) violated

--initially deferred:constraint被延迟,transaction commit时transaction会变成immediate
insert into scott.test values ( 1,-1 );
1 row created.
commit;
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02290: check constraint (SCOTT.CHECK_Y) violated

--转换initially deferred=>immediate
set constraint scott.check_y immediate;
insert into scott.test values ( 1,-1 );
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CHECK_Y) violated

1)enable/disable validate/novalidate
enable/disable:      对未来的数据有约束/无约束
validate/novalidate: 对已有的数据有约束/无约束
启用约束:
enable( validate) :启用约束,创建索引,对已有及新加入的数据执行约束.
enable novalidate :启用约束,创建索引,仅对新加入的数据强制执行约束,而不管表中的现有数据.
禁用约束:
disable( novalidate):关闭约束,删除索引,可以对约束列的数据进行修改等操作.
disable validate :关闭约束,删除索引,不能对表进行 插入/更新/删除等操作.

注意:如果加约束到一个大表,那么ORACLE会LOCK这个表,然后SCAN所有数据,来判断是否符合CONSTRAINT的要求,在繁忙的系统里显然是不合适的。
      所以用enable、novalidate比较合适,因为ORACLE仅仅会LOCK表一小段时间来建立CONSTRAINT,当CONSTRAINT建立后再VALIDATE,这时检验数据是不会LOCK表
alter table scott.me_score disable validate constraint score_sid_fk;
alter table scott.me_score enable  novalidate constraint score_sid_fk;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21126685/viewspace-666776/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/21126685/viewspace-666776/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值