加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Oracle在重复列上创建主键/索引

(2015-05-25 22:32:35)
标签:

it

分类: Oracle

组合特性说明

 

  

Validate

Novalidate

已有记录

新增/删除记录

已有记录

新增/删除记录

Enable

Yes

Yes

No

Yes

Disable

Yes

No

No

No

Validate确保已有数据符合约束;

Novalidate不必考虑已有数据是否符合约束。

   

除非Novalidate被指定,Enable默认Validate

除非Validate被指定,Disable默认Novalidate

   

Enable ValidateEnable相同,检查已有记录和新增记录,确保都符合约束;

Enable Novalidate 允许已有记录不必满足约束条件,但新增/修改的记录必须满足;

Disable Validate禁用约束,删除约束上的索引,不允许修改任何被约束的记录;

Disable NovalidateDisable相同,禁用约束,删除约束上的索引,且允许修改被约束的记录。

 

创建测试表

SQL> create table pk1(id number(2),name varchar2(8));

表已创建。

SQL> insert into pk1 values(1,'abc');

已创建 1 行。

SQL> alter table pk1 add constraint pk_pk1 primary key(id); --设置主键约束。

表已更改。

SQL> create table fr1(id number(2),name varchar2(8));

表已创建。

SQL> insert into fr1 values(1,'abc');

已创建 1 行。

SQL> alter table fr1 add constraint fk_fr1 foreign key(id) references pk1(id);

表已更改。

 

--设置外键

 

测试外键下使用enable novalidate/disable novalidate的情况

SQL> insert into fr1 values(2,'aaa');

insert into fr1 values(2,'aaa')

*

1 行出现错误:

ORA-02291: 违反完整约束条件 (SYS.FK_FR1) - 未找到父项关键字

 

SQL> alter table fr1 disable novalidate constraint fk_fr1;

表已更改。

 

SQL> insert into fr1 values(2,'aaa');

已创建 1 行。

 

SQL> select * from fr1;

ID NAME

---------- --------

1 abc

2 aaa

 

SQL> alter table fr1 enable validate constraint fk_fr1;

alter table fr1 enable validate constraint fk_fr1

*

1 行出现错误:

ORA-02298: 无法验证 (SYS.FK_FR1) - 未找到父项关键字

 

SQL> alter table fr1 enable novalidate constraint fk_fr1;

表已更改。

--从上面测试结果可见enable novalidatedisable novalidate在外键约束下使用是好用的。

 

测试主键下使用enable novalidate/disable novalidate的情况

SQL> select * from pk1;

ID NAME

---------- --------

1 abc

 

SQL> alter table pk1 disable novalidate primary key;

alter table pk1 disable novalidate primary key

*

1 行出现错误:

ORA-02297: 无法禁用约束条件 (SYS.PK_PK1) - 存在相关性

 

SQL> alter table fr1 disable validate constraint fk_fr1;

表已更改。

 

SQL> alter table pk1 disable novalidate primary key;

表已更改。

 

SQL> insert into pk1 values(1,'ccc');

已创建 1 行。

 

SQL> select * from pk1;

ID NAME

---------- --------

1 abc

1 ccc

 

SQL> alter table pk1 enable novalidate primary key;

alter table pk1 enable novalidate primary key

*

1 行出现错误:

ORA-02437: 无法验证 (SYS.PK_PK1) - 违反主键

 

SQL> select INDEX_NAME,TABLE_NAME,TABLE_OWNER from user_indexes where index_name

='PK_PK1';

未选定行

 

--主键对应的索引PK_PK1已经不在了。

SQL> create index cc on pk1(id);

索引已创建。

 

SQL> alter table pk1 enable novalidate primary key;

表已更改。

--OK了。

--从上面的测试结果看出:novalidate在非主键,唯一键时可以正常工作。在对主键,唯一键使用时需要先创建相关索引,再使用novalidatePrimary and unique keys must use nonunique indexes

 

举一个使用novalidate的案例:

给一个有数据的表增加一个非空的列。要求:需要在该表上增加一个字段status,但该字段不能为空,历史数据可以为空。最后将历史数据的该新加字段统一置为1

 

SQL> desc pk1;

名称 是否为空? 类型

----------------------------------------- -------- -------------

ID NOT NULL NUMBER(2)

NAME VARCHAR2(8)

 

SQL> select * from pk1;

ID NAME

---------- --------

1 abc

2 cba

 

SQL> alter table pk1 add status number(1);

表已更改。

 

SQL> alter table pk1 modify status not null enable novalidate;

表已更改。

 

SQL> select * from pk1;

ID NAME STATUS

---------- -------- ----------

1 abc

2 cba

 

SQL> update pk1 set status=1;

已更新2行。

 

SQL> commit;

提交完成。

 

SQL> select * from pk1;

ID NAME STATUS

---------- -------- ----------

1 abc 1

2 cba 1

 

SQL> insert into pk1 values(3,'bca',null);

insert into pk1 values(3,'bca',null)

*

1 行出现错误:

ORA-01400: 无法将 NULL 插入 ("SYS"."PK1"."STATUS")

 

 

除上之外还有一种简单的方法

先增加一列, alter table t add col number;

update table t set t.col=rownum;

然后alter table t add contstraint pk_t primary key (col

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有