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个字符
随机推荐
- Qt使用QNetworkAccessManager实现Ftp操作
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt使用QNetworkAccessManager实现Ftp操作 本文地址:http: ...
- 弱网络模拟测试工具---易测app
易测功能介绍 易测是一款基于无线客户端研发场景的通用测试工具, 它通过在研发人员的自持机上提供各种辅助能力&标准化的专项测试服务来提升研发质量&效率. 易测app是阿里巴巴做的 ...
- hdu mophues
在比赛的时候,被这个题目虐死了,这一周中每当我有空闲时间我就总是思索这个题目的解题方法. 终于在自己学过了mobius反演,并且看过别人写得解题思路后自己有了思路. 下面说说我的解题思路吧. 首先题目 ...
- Android四大组件之Intent
Intent不是android几大组件框架,但是确实是android 各大组件之间沟通的桥梁. 尤其Intent对于activity有很大的关系. 一下是我个人对task以及backstack的总结.
- [十五]SpringBoot 之 启动加载数据
实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求. 为了解决这样的问题,spring Boot 为我们提供了一个方法,通过实现接口 CommandLineRunner 来 ...
- 洛谷 P1495 曹冲养猪
这是一道标准的孙子定理的题,题意浅显,思路明确 然后我就交了整整16遍啊,欺负人啊,题解暴力就能过,我就TLE ..悲惨的提交记录 下面是题面 题目描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干 ...
- 520的信心赛——点点玩deeeep
3.点点玩 deeeep(deeeep.cpp) 描述 点点最近迷上了 deeeep(此 de 非彼 de),在研究一个特殊的最长树链问题 ...
- 在 Android开发中,性能优化策略十分重要
在 Android开发中,性能优化策略十分重要本文主要讲解性能优化中的布局优化,希望你们会喜欢.目录 示意图 1. 影响的性能 布局性能的好坏 主要影响 :Android应用中的页面显示速度 2. 如 ...
- 【MVVM 原生】原生MVVM的使用
一.前言 前些天需要完成一个任务,该任务属于公司的一些核心代码,为了避免不必要的麻烦,任务要求不能使用第三方的MVVM框架,必须用原生的. 平时习惯了Dev与MVVMLight,遇上原生的 ...
- python基础(4)
条件判断和循环 条件判断 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,用if语句实现: age = 20 if ag ...