Oracle笔记之约束
约束用于保证数据库中某些数据的完整性,给某一列添加一个约束可以保证不满足约束的数据是绝对不会被接受的。
约束主要有那么五种类型:非空约束、唯一约束、主键约束、外键约束、校验约束。
使用如下命令检索某个表上的所有约束(需要注意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笔记之约束的更多相关文章
- Oracle笔记 目录索引
Oracle笔记 一.oracle的安装.sqlplus的使用 Oracle笔记 二.常用dba命令行 Oracle笔记 三.function .select Oracle笔记 四.增删改.事务 Or ...
- 韩顺平Oracle笔记
韩顺平Oracle笔记 分类: DataBase2011-09-07 10:24 3009人阅读 评论(0) 收藏 举报 oracle数据库sqljdbcsystemstring 目录(?)[-] ...
- Oracle笔记 多表查询
Oracle笔记 多表查询 本次预计讲解的知识点 1. 多表查询的操作.限制.笛卡尔积的问题: 2. 统计函数及分组统计的操作: 3. 子查询的操作,并且结合限定查询.数据排序.多表查询.统计查 ...
- 转:oracle笔记
oracle笔记1 卸载oracle developer server的方法: 1-1 oracle卸载工具中卸载对应的oracleds项目:在注册表中搜索ORACLEDS HOME对应的别名,删除对 ...
- oracle笔记
一.sql*plus常用命令 (1)connect 用法:conn 用户名/密码@网络服务名[as sysdba/sysoper] 当特权用户连接时,必须带上as sysdba或是as sysoper ...
- oracle 笔记
1.Oracle认证,与其它数据库比较,安装 Oracle安装会自动的生成sys用户和system用户: (1)sys用户是超级用户,具有最高权限,具有sysdba角色,有create databas ...
- Oracle笔记(1) 简单查询、限定查询、数据的排序
Oracle笔记(四) 简单查询.限定查询.数据的排序 一.简单查询 SQL(Structured Query Language) 结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及 ...
- 改写了禁用或启用oracle数据库的约束的存储过程
改写了网上某位大侠(最开始的源头是哪位没记住)写的禁用或启用oracle数据库所有约束的存储过程,增加了异常控制,以使发生异常时也可以执行下去. –调用过程: 执行前先 set serveroutpu ...
- oracle中,约束、表名、Index等的名称长度限制最大只能30个字符
oracle中,约束.表名.Index等的名称长度限制最大只能30个字符
随机推荐
- DBGRID控件里可以实现SHIFT复选吗?怎么设置?
////////////////////////////////////////////////// 功能概述:公用的列表框选择框,是用DBGrid网格//// 注意事项:希望用Query ...
- 【计算机基础】当你在浏览器中输入Google.com并且按下回车之后发生了什么?
本文转载自:https://github.com/skyline75489/what-happens-when-zh_CN#id9 按下"g"键 接下来的内容介绍了物理键盘和系统中 ...
- inline函数的总结
在函数返回类型前加上关键字inline就可以将函数指定为内联函数: inline const string& shortString(const string &s1, const s ...
- 第200天:js---常用string原型扩展
一.常用string原型扩展 1.在字符串末尾追加字符串 /** 在字符串末尾追加字符串 **/ String.prototype.append = function (str) { return t ...
- java finally 与return
finally之外的语句块有return,finally语句块没有return:该语句块的返回值被固定下来,等fianlly执行完后返回给调用者 finally语句块与其他语句块同时有return:返 ...
- 【loj6307】「雅礼国庆 2017 Day1」Clique 贪心
题目描述 数轴上有 $n$ 个点,第 $i$ 个点的坐标为 $x_i$ 权值为 $w_i$ .两个点 $i,j$ 之间存在一条边当且仅当 $|x_i−x_j|\le w_i+w_j$ . 你需要求出这 ...
- Java虚拟机内存模型和volatile型变量
Java虚拟机内存模型 了解Java虚拟机的内存模型,有助于我们明白为什么会发生线程安全问题. 上面这幅图是<深入理解Java虚拟机-JVM高级特性与最佳实践>的书中截图. 线程共享的变量 ...
- Contest 7
A:搜索好难啊根本不会啊. B:原题都能写挂没救了啊.考虑求出每个数作为最小值时能向左向右扩展到的最远位置,那么这段区间里的所有数就不可能作为唯一的最小值成为最优解了,否则假设可以的话这段区间里的数都 ...
- [BJWC2018]Border 的四种求法
description luogu 给一个小写字母字符串\(S\),\(q\)次询问每次给出\(l,r\),求\(s[l..r]\)的\(Border\). solution 我们考虑转化题面:给定\ ...
- Linux学习笔记一:Linux配置java环境变量
一.安装JDK: 1.创建JDK的安装目录: sudo mkdir /usr/jdk 2.将jdk-7u25-linux-x64.tar.gz拷贝至/usr/jdk目录下 sudo cp jdk-7u ...