Oracle笔记(十) 约束
表虽然建立完成了,但是表中的数据是否合法并不能有所检查,而如果要想针对于表中的数据做一些过滤的话,则可以通过约束完成,约束的主要功能是保证表中的数据合法性,按照约束的分类,一共有五种约束:非空约束、唯一约束、主键约束、检查约束、外键约束。
一、非空约束(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) - 未找到父项关键字
因为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负责。
相关推荐
《MLDN最经典的ORACLE笔记》是李兴华老师倾力打造的一份全面而深入的Oracle学习资源,专为对数据库技术感兴趣的读者精心准备。Oracle作为全球广泛使用的数据库管理系统,其强大功能和复杂性使得深入理解和掌握Oracle...
这篇史上最全的Oracle笔记将为你提供全面的学习指导。 一、数据库基础 数据库(DataBase)是存储数据的系统,Oracle数据库允许用户以表格的形式组织和管理数据。在Oracle中,数据主要以表的形式存在,表是数据库中...
oracle笔记约束,如何创建一个约束,删除约束,在创建表的同时创建约束,在创建表之后创建约束,有具体详细的代码案例!
Oracle 数据库约束笔记 Oracle 数据库约束是一种机制,用于确保数据库数据的完整性和一致性。约束是指在数据库中强制执行某些规则,以确保数据的正确性和一致性。Oracle 数据库提供了多种类型的约束,包括 NOT NULL...
本笔记主要探讨了两个关键概念:约束和索引,这些都是Oracle数据库中的基础但至关重要的元素。 **1. 约束(Constraints)** 约束是Oracle数据库中用于确保数据完整性的规则。它们分为以下几种类型: - **非空约束...
在数据库对象方面,Oracle笔记详细介绍了表的创建和管理,包括数据类型、约束条件、索引的创建和使用。索引是提升查询性能的关键,笔记会涵盖B树索引、位图索引、函数索引等多种类型,并解释它们的适用场景。此外,...
这篇笔记主要涵盖了Oracle SQL的基础知识、高级特性和实际应用技巧。 一、基础SQL语法 Oracle SQL遵循标准的SQL语法,包括SELECT、INSERT、UPDATE、DELETE四大语句。用于查询数据的基本结构是SELECT字段列表FROM...
### 韩顺平Oracle视频笔记知识点概览 #### 1. Oracle 用户管理 - **概念**:在Oracle数据库中,用户是用来管理访问权限的基本单位。每个用户都可以有自己的模式(schema),其中包含各种对象如表、视图等。 - **创建...
Oracle数据库是世界上最流行的关系型数据库管理系统之一,广泛应用于企业级数据管理、数据分析和应用程序开发。以下将详细阐述Oracle的一些核心知识点。 1. **基础概念和术语**: - **关系型数据库**: 数据以表格...
以下是对Oracle数据库课堂笔记的详细解析,涵盖了从基础到进阶的重要知识点。 第一讲:Oracle简介 Oracle数据库是由甲骨文公司开发的,提供了一整套数据存储、管理和检索解决方案。它支持多种操作系统和硬件平台,...
### Oracle韩顺平笔记知识点概览 #### 第一章:Oracle基础介绍 ##### 第一节:Oracle的安装和启动 1. **数据库分类与选择**:数据库根据负载量、成本和安全需求分为小型(如Access、Foxbase)、中型(如MySQL、...
5. **04-习题讲解2及表的创建、约束.pdf**:这部分可能讲解如何在Oracle中创建表,包括字段定义、数据类型选择,以及约束的设定,如主键、外键、唯一性约束等。 6. **05-视图、索引、备份、同义词、设计范式、设计...
李兴华 Oracle 笔记是李兴华的 Oracle 笔记,涵盖了 Oracle 数据库的基本概念、SQL 语句、数据查询、数据更新操作、事务处理操作、数据表的定义与管理、约束的设置、数据伪列的使用、SQL Developer 工具的使用等知识...
│ ORACLE的索引和约束详解 - Oracle10g - 沪城篱笆.mht │ oracle里常用命令 - Oracle - 51CTO技术论坛_中国领先的IT技术社区.mht │ Sequence相关操作命令 - lvhuiqing的专栏 - CSDN博客.mht │ Sequence相关操作...
以上只是Oracle数据库知识体系的冰山一角,Oracle笔记中可能涵盖了这些内容的详细解释和实例演示,对于学习和理解Oracle数据库的操作和管理非常有帮助。在实际工作中,掌握这些知识能够帮助数据库管理员和开发者更...
在创建主键或唯一约束时,Oracle会自动创建唯一索引。创建唯一索引的命令是`CREATE UNIQUE INDEX index ON table (column)`。这种索引对于保持数据的完整性至关重要,但插入和更新操作会因索引的维护而产生额外的...