`
changhongbao
  • 浏览: 116823 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Oracle笔记(十) 约束

 
阅读更多

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负责。

分享到:
评论

相关推荐

    oracle 数据库约束笔记

    oracle 数据库约束笔记oracle 数据库约束笔记

    Oracle 入门文档2

    Oracle笔记 五、创建表、约束、视图、索引、序列、同义词、表空间 Oracle笔记 六、PL/SQL简单语句块、变量定义 Oracle笔记 七、PL/SQL 异常处理 Oracle笔记 八、PL/SQL跳转/判断/循环语句块 Oracle笔记 九、PL/...

    oracle笔记约束

    oracle笔记约束,如何创建一个约束,删除约束,在创建表的同时创建约束,在创建表之后创建约束,有具体详细的代码案例!

    Oracle 入门文档

    Oracle笔记 五、创建表、约束、视图、索引、序列、同义词、表空间 Oracle笔记 六、PL/SQL简单语句块、变量定义 Oracle笔记 七、PL/SQL 异常处理 Oracle笔记 八、PL/SQL跳转/判断/循环语句块 Oracle笔记 九、PL/...

    oracle约束和索引笔记

    自己看视频做的笔记,以后再更新,虽然内容很少,但是一看就懂。我也是菜鸟,所以笔记都是菜鸟笔记

    Oracle数据库笔记大全

    oracle的基础概念和术语,oracle的安装与卸载,创建存储过程,约束,oracle连接超时,服务的作用,创建表空间,用户,赋予权限

    Oracle 10g 学习笔记

    │ ORACLE的索引和约束详解 - Oracle10g - 沪城篱笆.mht │ oracle里常用命令 - Oracle - 51CTO技术论坛_中国领先的IT技术社区.mht │ Sequence相关操作命令 - lvhuiqing的专栏 - CSDN博客.mht │ Sequence相关操作...

    oracle 笔记.txt

    RACLE笔记(1) 收藏 Oracle SQL(Oracle 9i 9.2.0.1.0) SQL(结构化查询语言),是操作关系型数据库中的对象。 DDL(数据定义语言),用于建表或删表操作,以及对表约束进行修改。 DML(数据操作语言),向表中插入...

    oracle ebs 学习笔记

    个人对于oracle ebs的学习笔记和心得

    韩顺平oracle学习笔记

    韩顺平oracle学习笔记 第0讲:如何学习oracle 一、如何学习oracle Oracle目前最流行的数据库之一,功能强大,性能卓越。学习oracle需要具备一定基础: 1.学习过一门编程语言(如:java ,c) 2.最好学习过一门别的...

    oracle学习笔记(txt格式,自己总结的,很详细,每章附有例题和习题及答案)

    oracle学习笔记,txt格式,完全是自己总结的,特别详细,有例子,还有练习题以及答案。包括1.基本SQL语句 2.限制和排列数据 3.单行函数 4.多表查询 5.组函数 6.子查询 7.数据操作 8.创建和维护表 9.约束 10.创建视图...

    ORACLE笔记

    ORACLE学习笔记(入门级) SQL(结构化查询语言),是操作关系型数据库中的对象。 DDL(数据定义语言),用于建表或删表操作,以及对表约束进行修改。 DML(数据操作语言),向表中插入纪录,修改纪录。

    Oracle数据库学习笔记

    Oracle数据库学习笔记,包括课程PPT(数据库基础,简单查询,单行多行函数,多表连接,子查询,高级子查询,集合运算,层次查询,DML与事务控制,数据库的网络连接,创建维护表,约束,视图,序列索引和同义词,用户...

    oracle所有知识点笔记(全)

    这是我自己学习oracle的时候,写的代码案例和笔记,基本上每一个知识点都写的很清楚!大家可以作为参考! 该有的知识点都有! 基本的sql语法,触发器,存储过程,存储函数, 流程控制,游标,异常处理,记录类型,...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 第一章 Oracle入门 一、 数据库概述 数据库(Database)是按照数据结构来组织、存储和管理数据的仓库,它产生于距今五十年前。简单来说是本身可视...

    oracle全程笔记及代码

    完整性约束是指数据的正确性与完备性。 1)表:具有行列结构,每一行成为记录,每一列成为字段,字段都是有类型的。 2)数据操作:数据的创建数据的修改数据的删除数据的查询等,这些基本的操作被称为SQL...

    oracle数据库笔记

    Oracle 10g 开发与管理 本文是由笔者2012年学习oracle数据库时编写的学习札记,其中的题目 多数为老师留下的思考题目。 我相信本文会对初学者使用oracle有一个初步的使用印象。右图为我所参 考的书籍。 第一...

    oracle培训18天笔记

    从最基础的oracle的crud操作,oracle 基础, 包括SQLPLUS下的常用命令,ORACLE中字段的数据类型,建表,建约束,常用函数介绍,创建表空间、存储过程、触发器、游标使用等。

    Oracle10g学习笔记整理

    Oracle10g学习笔记整理:登录oracle、常用命令、SQL语言包含4个部分、创建表空间、创建/修改/删除用户、权限与角色的操作、建表语句、表的修改、约束、DML(查询SELECT、插入INSERT、修改UPDATE和删除DELETE数据)、...

Global site tag (gtag.js) - Google Analytics