Oracle基础知识笔记(10) 约束
表尽管建立完毕了,可是表中的数据是否合法并不能有所检查,而假设要想针对于表中的数据做一些过滤的话,则能够通过约束完毕,约束的主要功能是保证表中的数据合法性,依照约束的分类,一共同拥有五种约束:非空约束、唯一约束、主键约束、检查约束、外键约束。
一、非空约束(NOT NULL):NK
当数据表中的某个字段上的内容不希望设置为null的话,则能够使用NOT NULL进行指定。
范例:定义一张数据表
- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL
- );
由于此时存在了“NOT NULL”约束,所以以下插入两组数据。
范例:正确的数据
- INSERT INTO member(mid,name) VALUES(1,'张三');
- INSERT INTO member(mid,name) VALUES(null,'李四');
- INSERT INTO member(name) VALUES('王五');
范例:插入错误的数据
- INSERT INTO member(mid,name) VALUES(9,null);
- INSERT INTO member(mid) VALUES(10);
此时了出现的错误提示:
- ORA-01400: 无法将 NULL 插入 ("SCOTT"."MEMBER"."NAME")
本程序之中,直接表示出了“用户”.“表名称”.“字段”出现了错误。
二、唯一约束(UNIQUE):UK
唯一约束指的是每一列上的数据是不同意反复的,比如:email地址每一个用户肯定是不反复的,那么就使用唯一约束完毕。
- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- email VARCHAR2(50) UNIQUE
- );
范例:插入正确的数据
- INSERT INTO member(mid,name,email) VALUES(1,'张三','mchina_tang@qq.com');
- INSERT INTO member(mid,name,email) VALUES(2,'李四',null);
范例:插入错误的数据 —— 反复数据
- INSERT INTO member(mid,name,email) VALUES(3,'王五','mchina_tang@qq.com');
此时会出现例如以下的错误提示:
- ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C005272)
但是这个时候的错误提示与之前的非空约束相比并不完好,由于如今仅仅是给出了一个代号而已,这是由于在定义约束的时候没有为约束指定一个名字,所以由系统默认分配了,并且约束的名字建议的格式“约束类型_字段”,比如:“UK_email”,指定约束名称使用CONSTRAINT完毕。

- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- email VARCHAR2(50),
- CONSTRAINT UK_email UNIQUE(email)
- );

以后再次添加错误数据时,提示信息例如以下:
- ORA-00001: 违反唯一约束条件 (SCOTT.UK_EMAIL)
已经能够非常明白的提示用户错误的位置。
三、主键约束(Primary Key):PK
主键约束 = 非空约束 + 唯一约束,在之前设置唯一的约束的时候发现能够设置为null,而假设如今使用了主键约束之后则不能为空,并且主键一般作为数据的唯一的一个标记出现,比如:人员的ID。
范例:建立主键约束
- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER PRIMARY KEY,
- name VARCHAR2(50) NOT NULL
- );
范例:添加正确的数据
- INSERT INTO member(mid,name) VALUES(1,'张三');
范例:错误的数据 —— 主键设置为null
- INSERT INTO member(mid,name) VALUES(null,'张三');
错误信息,与之前的非空约束的错误信息提示是一样的;
- ORA-01400: 无法将 NULL 插入 ("SCOTT"."MEMBER"."MID")
范例:错误的数据 —— 主键反复
- INSERT INTO member(mid,name) VALUES(1,'张三');
错误信息,这个错误信息就是唯一约束的错误信息,可是信息不明白,由于没起名字。
- ORA-00001: 违反唯一约束条件 (SCOTT.SYS_C005276)
所以为了约束的使用方便,以下为主键约束起一个名字。
- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid)
- );
此时,反复插入数据,则错误信息例如以下:
- ORA-00001: 违反唯一约束条件 (SCOTT.PK_MID)
从正常的开发角度而言,一张表一般都仅仅设置一个主键,可是从SQL语法的规定而言,一张表却能够设置多个主键,而此种做法称为复合主键,比如:參考例如以下代码:
- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid,name)
- );
在复合主键的使用之中,仅仅有两个字段的内容都一样的情况下,才被称为反复数据。
范例:插入正确的数据
- INSERT INTO member(mid,name) VALUES(1,'张三');
- INSERT INTO member(mid,name) VALUES(1,'李四');
- INSERT INTO member(mid,name) VALUES(2,'李四');
范例:插入错误的数据
- INSERT INTO member(mid,name) VALUES(1,'张三');
错误信息:
- ORA-00001: 违反唯一约束条件 (SCOTT.PK_MID)
可是从开发的实际角度而言,一般都不使用复合主键,所以这个知识仅仅是作为其相关的内容做一个介绍。仅仅要是数据表,永远都仅仅设置一个主键。
四、检查约束(Check):CK
检查约束指的是为表中的数据添加一些过滤条件,比如:
- 设置年龄的时候范围是:0~200;
- 设置性别的时候应该是:男、女;
范例:设置检查约束

- DROP TABLE member PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- sex VARCHAR2(10) NOT NULL,
- age NUMBER(3),
- CONSTRAINT pk_mid PRIMARY KEY(mid),
- CONSTRAINT ck_sex CHECK(sex IN('男','女')),
- CONSTRAINT ck_age CHECK(age BETWEEN 0 AND 200)
- );

范例:添加正确的数据
- INSERT INTO member(mid,name,sex,age) VALUES(1,'张三','男','26');
范例:添加错误的性别 —— ORA-02290: 违反检查约束条件 (SCOTT.CK_SEX)
- INSERT INTO member(mid,name,sex,age) VALUES(2,'李四','非','26');
范例:添加错误的年龄 —— ORA-02290: 违反检查约束条件 (SCOTT.CK_AGE)
- INSERT INTO member(mid,name,sex,age) VALUES(2,'李四','女','260');
检查的操作就是对输入的数据进行一个过滤。
五、主-外键约束
之前的四种约束都是在单张表中进行的,而主-外键约束是在两张表中进行的,这两张表是存在父子关系的,即:子表中某个字段的取值范围由父表所决定。
比如,如今要求表示出一种关系,每个人有多本书,应该定义两张数据表:member(主)、book(子);

- DROP TABLE member PURGE;
- DROP TABLE book PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid)
- );
- CREATE TABLE book(
- bid NUMBER,
- title VARCHAR2(50) NOT NULL,
- mid NUMBER,
- CONSTRAINT pk_bid PRIMARY KEY(bid)
- );

此时仅仅是依据要求建立了两张独立的数据表,那么以下插入几条数据:

- INSERT INTO member(mid,name) VALUES(1,'张三');
- INSERT INTO member(mid,name) VALUES(2,'李四');
- INSERT INTO book(bid,title,mid) VALUES(101,'Java开发',1);
- INSERT INTO book(bid,title,mid) VALUES(102,'Java Web开发',2);
- INSERT INTO book(bid,title,mid) VALUES(103,'EJB开发',2);
- INSERT INTO book(bid,title,mid) VALUES(105,'Android开发',1);
- INSERT INTO book(bid,title,mid) VALUES(107,'AJAX开发',1);

要想验证这个数据是否有意义,最简单的做法,就是写两个查询。
范例:统计每一个人员拥有书的数量
- SELECT m.mid,m.name,COUNT(b.bid)
- FROM member m,book b
- WHERE m.mid=b.mid
- GROUP BY m.mid,m.name;
范例:查询出每一个人员的编号,姓名,拥有书的名称
- SELECT m.mid,m.name,b.title
- FROM member m,book b
- WHERE m.mid=b.mid;
即,如今的book.mid字段应该是与member.mid字段相关联的,可是因为本程序没有设置约束,所以,如今下面的数据也是能够添加的:
- INSERT INTO book(bid,title,mid) VALUES(108,'PhotoShop使用手冊',3);
- INSERT INTO book(bid,title,mid) VALUES(109,'FLEX开发手冊',8);
如今添加了两条新的记录,并且记录能够保存在数据表之中,可是这两条记录没有意义,由于member.mid字段的内容没有3和8,而要想解决问题就必须依靠外键约束来解决。
让book.mid的字段的取值由member.mid所决定,假设member.mid的数据真实存在,则表示能够更新。

- DROP TABLE member PURGE;
- DROP TABLE book PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid)
- );
- CREATE TABLE book(
- bid NUMBER,
- title VARCHAR2(50) NOT NULL,
- mid NUMBER,
- CONSTRAINT pk_bid PRIMARY KEY(bid),
- CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid)
- );

此时,仅仅是添加了一个约束,这样一来假设输入的数据有错误,则会出现例如以下的提示:
- ORA-02291: 违反完整约束条件 (SCOTT.FK_MID) - 未找到父项keyword
由于member.mid没有指定的数据,所以book.mid假设数据有错误,则无法运行更新操作。
使用外键的最大优点是控制了子表中某些数据的取值范围,可是相同带来了不少的问题;
1、 删除数据的时候,假设主表中的数据有相应的子表数据,则无法删除;
范例:删除member表中mid为1的数据
- DELETE FROM member WHERE mid=1;
错误提示信息:“ORA-02292: 违反完整约束条件 (SCOTT.FK_MID) - 已找到子记录”。
此时,仅仅能先删除子表记录,之后再删除父表记录:
- DELETE FROM book WHERE mid=1;
- DELETE FROM member WHERE mid=1;
可是这样的操作明显不方便,假设说如今希望主表数据删除之后,子表中相应的数据也能够删除的话,则能够在建立外键约束的时候指定一个级联删除的功能,改动数据库创建脚本:

- DROP TABLE member PURGE;
- DROP TABLE book PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid)
- );
- CREATE TABLE book(
- bid NUMBER,
- title VARCHAR2(50) NOT NULL,
- mid NUMBER,
- CONSTRAINT pk_bid PRIMARY KEY(bid),
- CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE CASCADE
- );

此时因为存在级联删除的操作,所以主表中的数据删除之后,相应的子表中的数据也都会被同一时候删除。
2、 删除数据的时候,让子表中相应的数据设置为null
当主表中的数据删除之后,相应的子表中的数据相关项也希望将其设置为null,而不是删除,此时,能够继续改动数据表的创建脚本:

- DROP TABLE member PURGE;
- DROP TABLE book PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- CONSTRAINT pk_mid PRIMARY KEY(mid)
- );
- CREATE TABLE book(
- bid NUMBER,
- title VARCHAR2(50) NOT NULL,
- mid NUMBER,
- CONSTRAINT pk_bid PRIMARY KEY(bid),
- CONSTRAINT fk_mid FOREIGN KEY(mid) REFERENCES member(mid) ON DELETE SET NULL
- );
- INSERT INTO member(mid,name) VALUES(1,'张三');
- INSERT INTO member(mid,name) VALUES(2,'李四');
- INSERT INTO book(bid,title,mid) VALUES(101,'Java开发',1);
- INSERT INTO book(bid,title,mid) VALUES(102,'Java Web开发',2);
- INSERT INTO book(bid,title,mid) VALUES(103,'EJB开发',2);
- INSERT INTO book(bid,title,mid) VALUES(105,'Android开发',1);
- INSERT INTO book(bid,title,mid) VALUES(107,'AJAX开发',1);

3、 删除父表之前必须首先先删除相应的子表,否则无法删除
- DROP TABLE book PURGE;
- DROP TABLE member PURGE;
可是这样做明显非常麻烦,由于对于一个未知的数据库,假设要依照此类方式进行,则必须首先知道其父子关系,所以在Oracle之中专门提供了一个强制性删除表的操作,即:不再关心约束,在删除的时候写上一句“CASCADE CONSTRAINT”。
- DROP TABLE member CASCADE CONSTRAINT PURGE;
- DROP TABLE book CASCADE CONSTRAINT PURGE;
此时,不关心子表是否存在,直接强制性的删除父表。
合理做法:在以后进行数据表删除的时候,最好是先删除子表,之后再删除父表。
六、改动约束
约束本身也属于数据库对象,那么也肯定能够进行改动操作,并且仅仅要是改动都使用ALTER指令,约束的改动主要指的是下面两种操作:
- 为表添加约束:
- ALTER TABLE 表名称 ADD CONSTRAINT 约束名称 约束类型(字段);
- 删除表中的约束:
- ALTER TABLE 表名称 DROP CONSTRAINT 约束名称;
能够发现,假设要维护约束,肯定须要一个正确的名字才干够,但是在这五种约束之中,非空约束作为一个特殊的约束无法操作,如今有例如以下一张数据表:
- DROP TABLE member CASCADE CONSTRAINT PURGE;
- CREATE TABLE member(
- mid NUMBER,
- name VARCHAR2(50) NOT NULL,
- age NUMBER(3)
- );
范例:为表中添加主键约束
- ALTER TABLE member ADD CONSTRAINT pk_mid PRIMARY KEY(mid);
添加数据:
- INSERT INTO member(mid,name,age) VALUES(1,'张三',30);
- INSERT INTO member(mid,name,age) VALUES(2,'李四',300);
如今在member表中已经存在了年龄上的非法数据,所以以下为member表添加检查约束:
- ALTER TABLE member ADD CONSTRAINT ck_age CHECK(age BETWEEN 0 AND 250);
这个时候在表中已经存在了违反约束的数据,所以肯定无法添加。
范例:删除member表中的mid上的主键约束
- ALTER TABLE member DROP CONSTRAINT pk_mid;
但是,跟表结构一样,约束最好也不要改动,并且记住,表建立的同一时候一定要将约束定义好,以后的使用之中建议就不要去改变了。
七、查询约束
在Oracle之中全部的对象都会在数据字典之中保存,而约束也是一样的,所以假设要想知道有哪些约束,能够直接查询“user_constraints”数据字典:
- SELECT owner,constraint_name,table_name FROM user_constraints;
可是这个查询出来的约束仅仅是告诉了你名字,而并没有告诉在哪个字段上有此约束,所以此时能够查看另外一张数据字典表“user_cons_columns”;
- COL owner FOR A15;
- COL constraint_name FOR A15;
- COL table_name FOR A15;
- COL column_name FOR A15;
- SELECT owner,constraint_name,table_name,column_name FROM user_cons_columns;
这些维护工作大部分由专门的DBA负责。
Oracle基础知识笔记(10) 约束的更多相关文章
- Oracle基础知识笔记
1.打开oracle相关服务 2.创建Oracle用户 create user 用户名 identified by 密码;(需要dba角色创建) 3.权限管理 (1)添加权限 grant 权限.角色 ...
- Oracle基础知识汇总一
Oracle基础知识 以下内容为本人的学习笔记,如需要转载,请声明原文链接 https://www.cnblogs.com/lyh1024/p/16720759.html oracle工具: SQ ...
- Oracle基础学习笔记
Oracle基础学习笔记 最近找到一份实习工作,有点头疼的是,有阶段性考核,这...,实际想想看,大学期间只学过数据库原理,并没有针对某一数据库管理系统而系统的学习,这正好是一个机会,于是乎用了三天时 ...
- Java多线程基础知识笔记(持续更新)
多线程基础知识笔记 一.线程 1.基本概念 程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程序的一次执行过程,或是 ...
- 图说Oracle基础知识(一)
本文主要对Oralce数据库操作的基础知识进行一下梳理,以便进行归纳总结.适用于未使用过Oracle数据库的读者,或需要学习Oracle数据库方面的基础知识.如有不足之处,还请指正. 关于SQL介绍的 ...
- JS基础知识笔记
2020-04-15 JS基础知识笔记 // new Boolean()传入的值与if判断一样 var test=new Boolean(); console.log(test); // false ...
- javascript基础知识笔记-自用
笔记内容根据个人基础知识不足不明白之处做的记录.主要看的:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript 1.变量,变量的名字又叫标识符 ...
- java基础知识-笔记整理
1.查看已安装jdk文件路径 CMD输入java -verbose. 2.java学习提升路线 java学习视屏地址: http://www.icoolxue.com/album/show/38 ...
- Oracle 基础知识入门
前记: 近来项目用到Oracle数据库,大学学了点,后面基本忘记得差不多了,虽然基本语法跟sql 差不多,但是oracle知识是非常多的. 这里简单说点基础知识,希望后面补上更多的关于ORacle知识 ...
随机推荐
- vim Ctags 和taglist安装和使用
Ctags是一个用于从程序源代码树产生索引文件(或tag文件),从而便于文本编辑器来实现快速定位的实用工具.在产生的tag文件中,每一个tag的入口指向了一个编程语言的对象.这个对象可以是变量定义.函 ...
- perl学习(2) 基本数据类型等
1.1.数字 所有数字格式内部一致,全部是double 7.25e45 == 7.25 * 1045 5.25 6.00 5.1-2.4 #5.1-2.4,2.7 10/3 ...
- php 用户访问菜单页面,必须登录,判断用户是否登录
<pre name="code" class="python"># 本节课大纲: 一.空模块和空操作 1.空操作 function _empty($ ...
- 链接分析算法之:HillTop算法
链接分析算法之:HillTop算法 Hilltop算法是由Krishna Baharat 在2000年左右研究的,于2001年申请专利,但是有很多人以为Hilltop算法是由谷歌研究的.只 ...
- linux之文本编辑器
[目标] 管理员在进行系统操作的时候,不可避免地会对文本进行修改,如进行各种服务程序配置文件的修改,使程序对用户提供不同的服务效果.在本章我们向大家介绍Linux上常见的编辑器ed.vi.emacs, ...
- 记录一次SQL查询语句
以前发现比较经典的句子,都是记录在电脑上,我今天想搬到博客上,在我看来,写博客真的是一件非常头疼的事,它是内心的一道坎,我必须得跨过它. CREATE TABLE t_jeff ( id int NO ...
- C#_会员管理系统:开发六(数据搜索)
增加界面中的搜索功能 会员资料管理界面(VIPManager.cs): 详细代码如下: using System; using System.Collections.Generic; using Sy ...
- uboot编译: uboot编译配置和编译过程
jz2440: 韦东山Linux视频第1期_裸板_UBoot_文件系统_驱动初步\第09课第2节 u-boot分析之Makefile结构分析.WMV <嵌入式linux完全开发手册> 15 ...
- iOS 8 强制横屏
最近用到视频播放功能:(Vitamio, 注:在Build Setting 里面的 Other Link Flag 添加-all_load) iOS 8的屏幕旋转比较坑, 使用以下代码可以强制旋转 - ...
- [转] iOS应用架构谈 网络层设计方案
原文地址:http://casatwy.com/iosying-yong-jia-gou-tan-wang-luo-ceng-she-ji-fang-an.html iOS应用架构谈 开篇 iOS应用 ...