1 2 3 4

oracle约束

oracle约束

  • 非空
  • 默认
  • 唯一
  • 检查
  • 自增(序列)
  • 主键
  • 外键

一,非空约束

  • 被约束的列不能为空

1建表时在类型长度后面加not null,指明非空

SQL> create table con_test1
  2  (
  3  con_id number(6) not null,
  4  con_name varchar(60),
  5  con_age number(3)
  6  );

表已创建。
SQL> insert into con_test1 values(null,'gent',null);
ORA-01400: 无法将 NULL 插入 ("SCOTT"."CON_TEST1"."CON_ID")
SQL> insert into con_test1 values(1,'gent',null);
已创建 1 行。

2更改列属性指定非空

删除原有数据

SQL> delete from con_test1 where con_id=1;
已删除 1 行。

更改列属性,指定非空

SQL> alter table con_test1 modify con_age not null;
表已更改。
SQL> insert into con_test1 values(1,'gent',null);
ORA-01400: 无法将 NULL 插入 ("SCOTT"."CON_TEST1"."CON_AGE")

3移除非空约束

SQL> alter table con_test1 modify con_age null;
表已更改。

SQL> insert into con_test1 values(1,'gent',null);
已创建 1 行。

二,默认约束

  • 默认约束指定某列的默认值

如果男性同学较多,性别就可以默认为'男'
当插入一条新的记录时,没有为这个字段赋值,那么系统就会自动为这个字段赋值为'男'

1建表时设置

SQL> create table default_test1
  2  (
  3  dt_id number(6),
  4  dt_name varchar(60),
  5  dt_date date,
  6  dt_sex varchar(10) default '男'
  7  );

表已创建。
SQL> insert into default_test1 values(1,'gent',sysdate,'');
已创建 1 行。

SQL> insert into default_test1 values(2,'land',sysdate,null);
已创建 1 行。

SQL> insert into default_test1 values(3,'teng',sysdate,'女');
已创建 1 行。

SQL> insert into default_test1(dt_id,dt_name,dt_date) values(4,'rund',sysdate);
已创建 1 行。
SQL> select * from default_test1;

     DT_ID DT_NAME              DT_DATE      DT_SEX
---------- -------------------- -------------- ------------
         1 gent                 27-11月-19
         2 land                 27-11月-19
         3 teng                 27-11月-19           女
         4 rund                 27-11月-19           男

2建表后设置

SQL> alter table default_test1 modify dt_date default sysdate;

表已更改。

SQL> insert into default_test1(dt_id,dt_name) values(5,'lauy');

已创建 1 行。

SQL> select * from default_test1
  2  where dt_id=5;

     DT_ID DT_NAME           DT_DATE      DT_SEX
---------- ----------------- -------------- ------------
         5 lauy              27-11月-19           男

3删除设置的默认约束

SQL> alter table default_test1 modify dt_sex default null;
表已更改。

SQL> insert into default_test1(dt_id,dt_name) values(6,'auny');
已创建 1 行。
SQL> select * from default_test1
  2  where dt_id=6;

     DT_ID DT_NAME             DT_DATE      DT_SEX
---------- ------------------- -------------- -------------
         6 auny                27-11月-19

三,唯一约束

  • 被约束的列是唯一的
  • 可以多行为空

1建表时设置

  • 建表时在类型长度后加constraint 约束名 unique;
  • 建表语句新加一行, constraint 约束名 unique(列名);
SQL> create table con_test2
  2  (
  3  con_id number(6) constraint unique_contest2_id unique,
  4  con_name varchar(60),
  5  con_age number(3),
  6  constraint unique_contest_name unique(con_name)
  7  );

表已创建。

2建表后通过alter设置

语法

alter table 表名 add constraint 约束名 unique(约束列名);
SQL> alter table con_test2 add constraint unique_contest2_age unique(con_age);

表已更改。

移除唯一约束

SQL> alter table con_test2 drop constraints unique_contest2_age;

表已更改。

四,检查约束

  • 规定每一列能够输入的值,从而确保数值的正确性

当姓名字段中规定只能输入男或者女,此时可以用到检查约束

1建表时创建

sex字段只能为男或者女
age字段值的范围为1-165,包含边界值

SQL> create table check_test1
  2  (
  3  id number(6) primary key,
  4  name varchar(60) not null,
  5  sex varchar(6) constraint check_sex check(sex='男' or sex='女'),
  6  age number(3),
  7  email varchar(200),
  8  constraint check_age check(age between 1 and 165)
  9  );

表已创建。

2建表后添加

设置email字段值中必须包含@符号

SQL> alter table check_test1 add constraint check_email check(email like '%@%');

表已更改。

3删除检查约束

SQL> alter table check_test1 drop constraints check_age;

表已更改。

五,自增(序列)约束

  • 序列是一串有序的数字
  • 在oracle12c新增自增功能,通过为表主键添加generated by default as identity
  • 在oracle12c之前可以通过序列实现自增功能
SQL> create table seq_table
  2  (
  3  id number(6),
  4  name varchar(60)
  5  );

表已创建。
SQL> create sequence seq_test
  2  start with 1
  3  increment by 1
  4  nomaxvalue
  5  nocycle
  6  cache 10;

序列已创建。
SQL> insert into seq_table(id,name) values(seq_test.nextval,'张三');
已创建 1 行。

SQL> insert into seq_table(id,name) values(seq_test.nextval,'李四');
已创建 1 行。
SQL> select * from seq_table;

        ID NAME
---------- ------
         1 张三
         2 李四
关键字 描述
create sequence 序列名--序列的名字,以SEQ_开头
start with 数值 --起始值(可不写)
minvalue 数值 --序列最小值
maxvalue 数值 --序列最大值(nomaxvalue不设置最大值)
increment by 数值 --每次增长大小,也叫步长
cache 数值 --缓冲池大小,若表中插入数据较多,则cache可以设置为1000. ceil(最大值-最小值)/ABS(步长)
cycle; --是否循环(即达到最大值后重新从最小值开始),不写默认为不循环.

删除序列

SQL> drop sequence seq_test;

序列已删除。

六,主键

  • 不为空且不重复的一列数据
  • 确定一条记录的唯一性

1单列主键

1.1创建表时设置

列级别

不能自定义表名称

SQL> create table pktest1
  2  (
  3  id1 number(8) primary key,
  4  name1 varchar(60)
  5  );

表已创建。
表级别
SQL> create table pktest2
  2  (
  3  id2 number(8),
  4  name2 varchar(60),
  5  constraint PK_pktest2_id2 primary key(id2)
  6  );

表已创建。

PK_pktest2_id2为主键名称

1.2更改属性时设置

SQL> create table pktest3
  2  (
  3  id3 number(8),
  4  name3 varchar(60)
  5  );

表已创建。
SQL> alter table pktest3 add constraint PK_pktest3_id3 primary key(id3);

表已更改。

1.3先设置表索引,再设置主键,能够优化查询速度

SQL> create table pktest4
  2  (
  3  id4 number(8),
  4  name4 varchar(60)
  5  );

表已创建。
SQL> create unique index PK_pktest4_id4 on pktest4(id4);

索引已创建。
SQL> alter table pktest4 add constraint PK_pktest4_id4 primary key(id4);

表已更改。

索引名称可以和主键名称相同

复合主键

  • 如果表中没有单列能够确定数据的唯一性,可以指定多列来确定数据的唯一性

2.1创建表时设置

SQL> create table pktest5
  2  (
  3  id5 number(8),
  4  name5 varchar(60),
  5  age number(3),
  6  constraint PK_pktest5_idname5 primary key(id5,name5)
  7  );

表已创建。

2.2更改属性时设置

SQL> create table pktest6
  2  (
  3  id6 number(8),
  4  name6 varchar(60),
  5  age number(3)
  6  );

表已创建。
SQL> alter table pktest6 add constraint PK_pktest6_idname6 primary key(id6,name6);

表已更改。

七,外键

  • 子表的数据依赖于父表数据,所依赖的父表列必须是主键或者有唯一约束
  • 外键以FK_开头,名字唯一

  • 没有写on delete cascade和on delete set null时,只有外键没有相关联的数据时,才能删除主表
  • 有on delete cascade(级联删除)删除父表数据,子表数据也会跟随删除;
  • 有on delete set null时,删除父表数据,子表数据约束列会被置空;
SQL> create table FKtest1
  2  (
  3  id1 number(6),
  4  name1 varchar(60)
  5  );
表已创建。

SQL> create table FKtest2
  2  (
  3  id2 number(6),
  4  name2 varchar(60)
  5  );
表已创建。
SQL> alter table FKtest1 add constraint PK_FKtest1_id1 primary key(id1);
表已更改。
SQL> insert into FKtest1 values(1,'张三');
已创建 1 行。

SQL> insert into FKtest1 values(2,'李四');
已创建 1 行。

SQL> insert into FKtest1 values(3,'王五');
已创建 1 行。

SQL> insert into FKtest2(id2,name2) select id1,name1 from FKtest1;
已创建3行。

1简单写法

没有on delete casecade或者set null时,子表数据必须在父表中(约束列),删除时须先删除子表,再删除父表;

语法

alter table 表名 add constraint FK_外键名 foreign key(列名) references 主表表名(列名);

范例

SQL> alter table FKtest2 add constraint FK_FKtest2_id2 foreign key(id2) references FKtest1(id1);
表已更改。

发现不能往test2表中插入主表列id没有的数据

SQL> insert into FKtest2 values(4,'赵六');

ORA-02291: 违反完整约束条件 (SCOTT.FK_FKTEST2_ID2) - 未找到父项关键字
SQL> insert into FKtest1 values(4,'赵六');
已创建 1 行。

SQL> insert into FKtest2 values(4,'赵六');
已创建 1 行。

删除时需要先删除字表数据,再删除父表数据

SQL> delete from FKtest1 where id1=4;

ORA-02292: 违反完整约束条件 (SCOTT.FK_FKTEST2_ID2) - 已找到子记录
SQL> delete from FKtest2 where id2=4;
已删除 1 行。

SQL> delete from FKtest1 where id1=4;
已删除 1 行。

2级连删除

有on delete cascade(级联删除)删除父表数据,子表数据也会跟随删除;

删除上面范例中的外键约束

SQL> alter table FKtest2 drop constraints FK_FKtest2_id2;

表已更改。

新建级联约束

SQL> alter table FKtest2 add constraint FK_FKtest2_id2 foreign key(id2) references FKtest1(id1) on delete cascade;

表已更改。

发现同样不能往test2表中插入主表列id没有的数据

SQL> insert into FKtest2 values(4,'赵六');
ORA-02291: 违反完整约束条件 (SCOTT.FK_FKTEST2_ID2) - 未找到父项关键字


SQL> insert into FKtest1 values(4,'赵六');
已创建 1 行。

SQL> insert into FKtest2 values(4,'赵六');
已创建 1 行。

删除主表的数据时,test2表中的数据同时被也被删除了

SQL> delete from FKtest1 where id1=4;
已删除 1 行。

SQL> delete from FKtest2 where id2=4;
已删除0行。

3删除制空

删除上面创建的级联约束

SQL> alter table FKtest2 drop constraints FK_FKtest2_id2;
表已更改。

新建制空外键约束

SQL> alter table FKtest2 add constraint FK_FKtest2_id2 foreign key(id2) references FKtest1(id1) on delete set null;

表已更改。

同样不能不能往test2表中插入主表列id没有的数据

SQL> insert into FKtest2 values(4,'赵六');
ORA-02291: 违反完整约束条件 (SCOTT.FK_FKTEST2_ID2) - 未找到父项关键字

SQL> insert into FKtest1 values(4,'赵六');
已创建 1 行。

SQL> insert into FKtest2 values(4,'赵六');
已创建 1 行。

删除主表数据时,test2表会删除对应外键列的值

SQL> delete from FKtest1 where id1=1;

已删除 1 行。
SQL> select * from FKtest2;

   ID2   NAME2
--------------
          张三
  2      李四
  3      王五
posted @ 2019-11-28 16:57  多走多看  阅读(369)  评论(0编辑  收藏  举报