约束用于保证数据库中某些数据的完整性,给某一列添加一个约束可以保证不满足约束的数据是绝对不会被接受的。

约束主要有那么五种类型:非空约束、唯一约束、主键约束、外键约束、校验约束。

使用如下命令检索某个表上的所有约束(需要注意WHERE条件中的表名和用户名需要大写,不然检索不到):

SELECT *
FROM all_constraints
WHERE table_name = 'T_USER' AND owner = 'SCOTT';

结果如下:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005264 C T_ORDER "USER_ID" IS NOT NULL ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1
SCOTT SYS_C005266 R T_ORDER SCOTT SYS_C005258 NO ACTION ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1

对于上面的CONSTRAINT_NAME,如果在创建的时候不指定的话Oracle就会自动生成一个,自动生成的不能见名知义鬼知道什么意思...

对于上面的CONSTRAINT_TYPE:

C:校验约束,表

O:只读约束

P:主键约束

R:外键约束

U:唯一约束

V:校验约束,视图

使用下面这个命令查看列级别的约束:

SELECT * FROM user_cons_columns WHERE CONSTRAINT_NAME='FK_ORDER_USER';

列级约束定义:在定义列的时候定义的约束。

表级约束定义:在列定义完之后再定义的约束,注意这里并不一定是表创建完成之后,只要在列声明完事之后再声明的就算是表级定义。

列级的定义不能自己取约束名,Oracle会自动生成,自动生成的约束名类似这个样式的:SYS_C005271,一点也不友好啊,使用表级约束定义可以自己指定一个见名知义的约束名。

举个例子说明列级定义和表级定义:

列级定义主键:

CREATE TABLE t_user(
id INT PRIMARY KEY
);

表级定义主键:

CREATE TABLE t_user(
id INT ,
CONSTRAINT PK_USER_ID PRIMARY KEY (id)
);

约束的类型

非空约束(NOT NULL )

任何列都可以赋予一个NOT NULL约束,授予非空约束的列在插入数据的时候必须有数据,对于字符串类型的列,如果没有值可插入但是又有非空约束的话,那么传入一个空串即可,同理,对于数据类型的可以用0表示NULL,只要在业务上别有歧义。

设置非空约束是很有必要的,比如对于一些经常在WHERE条件中用到的被检索的字段如果有NULL的话就不能使用索引了。

创建表的时候指定非空约束:

CREATE TABLE t_user(
id INT PRIMARY KEY ,
username VARCHAR2(50) NOT NULL
);

查看t_user表中的约束:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005271 C T_ORDER "USERNAME" IS NOT NULL ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1
SCOTT SYS_C005272 P T_ORDER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1 SYS_C005272

一个C非空约束,一个P主键约束,为啥是C呢,因为这样啊:

username VARCHAR2(50) NOT NULL == username VARCHAR2(50) CHECK(username IS NOT NULL)

NOT NULL实际上就相当于添加了一个IS NOT NULL的CHECK。

表创建完毕再增加非空约束:

ALTER TABLE t_user MODIFY username NOT NULL;

删除非空约束:

ALTER TABLE t_user MODIFY username NULL;

唯一约束(UNIQUE)

如果将某个列设置为唯一,那么列中每行的数据不能重复,虽然不能重复,但是可以为null。

创建表的时候指定唯一约束:

CREATE TABLE t_user(
id INT PRIMARY KEY ,
username VARCHAR2(50) ,
email VARCHAR2(255) UNIQUE
);

查看t_user上的约束:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_USER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005280 U T_USER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 2 SYS_C005280
SCOTT SYS_C005279 P T_USER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 2 SYS_C005279

一个唯一约束,一个主键约束。

在创建完表之后再添加唯一约束:

ALTER TABLE t_user ADD CONSTRAINT U_EMAIL UNIQUE(email); 

添加多列唯一约束,多个列的值不重复即可:

ALTER TABLE emp ADD CONSTRAINT U_ENAME_JOB UNIQUE(ename, job);

删除表中的唯一约束:

ALTER TABLE t_user DROP CONSTRAINT SYS_C005280;

主键约束(PRIMARY KEY)

1. 主键列是非空且唯一的,相当于NOT NULL+UNIQUE

2. 每个表中最多可以有一个主键约束。

3. 主键约束可以由表中的一个列或多个列组成,多个列的话称之为复合主键。

4. 主键属于表对象,所以主键有一个对象,若没有给主键指定名字,Oracle会自动分配一个唯一的名字

创建表的时候指定主键:

CREATE TABLE t_user(
id INT PRIMARY KEY
);

创建复合主键:

CREATE TABLE t_user(
id INT ,
business_id INT ,
CONSTRAINT PK_USER PRIMARY KEY (id, business_id)
);

注意复合主键只能使用表级约束定义,因为没有办法在一个列上使用两个列啊...

表创建完成之后再指定主键:

ALTER TABLE t_user
ADD CONSTRAINT PK_USER_ID PRIMARY KEY(id);

删除主键:

ALTER TABLE t_user DROP PRIMARY KEY;

在删除主键的时候可能会有错误,比如某张表的主键已经是别的表的外键了,那么尝试删除父表的时候就会报错。

来建立一个主外键关系:

DROP TABLE t_user;
CREATE TABLE t_user(
id INT PRIMARY KEY
); DROP TABLE t_order;
CREATE TABLE t_order(
id INT PRIMARY KEY ,
user_id INT REFERENCES t_user(id)
);

t_order已经有一个外键指向了t_user的主键,尝试删除t_user的主键:

SQL> ALTER TABLE t_user DROP PRIMARY KEY;
ALTER TABLE t_user DROP PRIMARY KEY
ORA-02273: 此唯一/主键已被某些外键引用

正确的姿势上加上CASCADE,表示将外键主从关系一并删除掉:

ALTER TABLE t_user DROP PRIMARY KEY CASCADE;

再查看t_order表的约束关系:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005284 P T_ORDER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 2 SYS_C005284

只剩下一个主键约束了,外键约束已经被删除掉了。

外键约束(FOREIGN KEY)

1. 外键约束是为数据库中某个与其它表有关系的表而定义的。

2. 外键的值必须先出现在某个特定表的主键列或者有唯一约束的列中。

3. 外检的列可以包含NULL。

4. 一个表中外键可以有多个。

先创建一个用户表:

CREATE TABLE t_user(
id INT PRIMARY KEY ,
name VARCHAR2(50) NOT NULL
);

再创建一个订单表,链接到订单表:

CREATE TABLE t_order(
id INT PRIMARY KEY ,
user_id INT REFERENCES t_user(id) NOT NULL
);

查看t_order表的约束:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005268 P T_ORDER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1 SYS_C005268
SCOTT SYS_C005267 C T_ORDER "USER_ID" IS NOT NULL ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1
SCOTT SYS_C005269 R T_ORDER SCOTT SYS_C005258 NO ACTION ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1

可以看到有三个约束,一个是主键,一个是外键,一个是外键列的非空。

对于已经创建完成的表,需要添加外键应该怎么办呢。

先删除上面t_order的外键约束:

ALTER TABLE t_order DROP CONSTRAINT SYS_C005269;

需要注意删除约束的时候需要传入约束的名字,对于自动生成的可以先去查询出然后再删除。

现在t_order表就俩约束了:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005268 P T_ORDER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1 SYS_C005268
SCOTT SYS_C005267 C T_ORDER "USER_ID" IS NOT NULL ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1

来为其重新把外键约束添加上:

ALTER TABLE t_order
ADD CONSTRAINT FK_ORDER_USER FOREIGN KEY (user_id) REFERENCES t_user;

外键约束已添加上:

SQL> SELECT *
2 FROM all_constraints
3 WHERE table_name = 'T_ORDER' AND owner = 'SCOTT';
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------------------------------ ------------------------------ --------------- ------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------------------ ----------- -------- -------------- --------- ------------- -------------- --- ---- ----------- ------------------------------ ------------------------------ ------- --------------
SCOTT SYS_C005268 P T_ORDER ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1 SYS_C005268
SCOTT SYS_C005267 C T_ORDER "USER_ID" IS NOT NULL ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 2017/6/15 1
SCOTT FK_ORDER_USER R T_ORDER SCOTT SYS_C005258 NO ACTION ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED USER NAME 2017/6/15 1

校验约束(CHECK)

校验约束是一个布尔表达式,它的返回值是TRUE或者FALSE。

校验用于检查插入的数据是否合法,是“最后一层防线”(事实上还可以用触发器实现最后防线,即在插入数据后触发一个校验动作,不合法的话就抹掉它再报错)。

创建一个用户表:

CREATE TABLE t_user(
id INT PRIMARY KEY ,
name VARCHAR2(50) NOT NULL ,
age INT NOT NULL
);

为age字段添加一个检查约束:

ALTER TABLE t_user
ADD CONSTRAINT T_STUDENT_AGE_CHECK CHECK(age>=0 AND age<=100);

当然更优雅的写法是使用BETWEEN...AND...:

ALTER TABLE t_user
ADD CONSTRAINT T_STUDENT_AGE_CHECK CHECK(age BETWEEN 0 AND 100);

在WHERE中可以使用的,在CHECK表达式中都可以使用的。

创建表的时候添加校验约束:

CREATE TABLE t_user(
id INT PRIMARY KEY ,
name VARCHAR2(50) ,
age INT CHECK(age BETWEEN 0 AND 128)
);

表创建完毕添加校验约束:

ALTER TABLE t_user
ADD CONSTRAINT T_STUDENT_AGE_CHECK CHECK(age BETWEEN 0 AND 100);

删除校验约束:

ALTER TABLE t_user DROP CONSTRAINT T_STUDENT_AGE_CHECK ;

.

Oracle笔记之约束的更多相关文章

  1. Oracle笔记 目录索引

    Oracle笔记 一.oracle的安装.sqlplus的使用 Oracle笔记 二.常用dba命令行 Oracle笔记 三.function .select Oracle笔记 四.增删改.事务 Or ...

  2. 韩顺平Oracle笔记

    韩顺平Oracle笔记 分类: DataBase2011-09-07 10:24 3009人阅读 评论(0) 收藏 举报 oracle数据库sqljdbcsystemstring   目录(?)[-] ...

  3. Oracle笔记 多表查询

    Oracle笔记  多表查询   本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查 ...

  4. 转:oracle笔记

    oracle笔记1 卸载oracle developer server的方法: 1-1 oracle卸载工具中卸载对应的oracleds项目:在注册表中搜索ORACLEDS HOME对应的别名,删除对 ...

  5. oracle笔记

    一.sql*plus常用命令 (1)connect 用法:conn 用户名/密码@网络服务名[as sysdba/sysoper] 当特权用户连接时,必须带上as sysdba或是as sysoper ...

  6. oracle 笔记

    1.Oracle认证,与其它数据库比较,安装 Oracle安装会自动的生成sys用户和system用户: (1)sys用户是超级用户,具有最高权限,具有sysdba角色,有create databas ...

  7. Oracle笔记(1) 简单查询、限定查询、数据的排序

    Oracle笔记(四) 简单查询.限定查询.数据的排序   一.简单查询 SQL(Structured Query Language) 结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及 ...

  8. 改写了禁用或启用oracle数据库的约束的存储过程

    改写了网上某位大侠(最开始的源头是哪位没记住)写的禁用或启用oracle数据库所有约束的存储过程,增加了异常控制,以使发生异常时也可以执行下去. –调用过程: 执行前先 set serveroutpu ...

  9. oracle中,约束、表名、Index等的名称长度限制最大只能30个字符

    oracle中,约束.表名.Index等的名称长度限制最大只能30个字符

随机推荐

  1. QUdpSocket-Qt使用Udp通讯实现服务端和客户端

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:QUdpSocket-Qt使用Udp通讯实现服务端和客户端     本文地址:https:// ...

  2. redis 同步化操作

    异步化操作是很麻烦的的.不好控.下面介绍个同步化的库bluebird.用法很简单.看下你还子就知道了 const redis = require('redis'); const bluebird = ...

  3. 【C++】构造函数不能是虚函数

    1 虚函数对应一个vtable,这大家都知道,可是这个vtable其实是存储在对象的内存空间的.问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没 ...

  4. ROC曲线【转】

    受试者工作特征曲线(receiver operating characteristic curve, 简称ROC曲线),又称为感受性曲线(sensitivity curve).得此名的原因在于曲线上各 ...

  5. 获取网站图标Icon

    通常情况下,做网站的都会给自己的网站添加一个Icon,浏览器上一长排的标签页,用Icon来区分就显得更加醒目.现在想找一个没有Icon的网站并不好找,可见没有Icon的网站是多么的业余啊." ...

  6. 自动化测试断言Assent的使用

    Assent 断言模板包含如下方法: assert.fail(actual, expected, message, operator) assert.ok(value, [message]) asse ...

  7. 【Java】JAVA开发人员常见环境工具安装

    1.安装配置JDK1.7:jdk-7u45-windows-x64.exe,环境变量配置:JAVA_HOME---[F:\1024\jdk1.7],CLASSPATH---[.;%JAVA_HOME% ...

  8. 获取http和ftp地址的图片

    根据http和ftp图片地址获取对应图片的缩略图和原图 public class GetBitmapImageClass { public BitmapSource GetImageHttp(stri ...

  9. 【刷题】BZOJ 2754 [SCOI2012]喵星球上的点名

    Description a180285幸运地被选做了地球到喵星球的留学生.他发现喵星人在上课前的点名现象非常有趣. 假设课堂上有N个喵星人,每个喵星人的名字由姓和名构成.喵星球上的老师会选择M个串来点 ...

  10. 【WPF】GridControl的使用

    一.前言 在WPF中我们常常使用DataGrid来显示数据,在Dev中也有一个类似的控件—GridControl. 二.范例 <dxg:GridControl Grid.Row=" I ...