资源描述
·83·
Oracle PL/SQL从入门到精通
程序员典藏大系
Oracle PL/SQL从入门到精通
丁士锋 等编著
清 华 大 学 出 版 社
北 京
内 容 简 介
本书以面向应用为原则,深入浅出地介绍了Oracle平台上使用PL/SQL语言进行数据库开发的技术。通过大量的示例,详细介绍了PL/SQL的语言特性、使用技巧,同时配以两个在实际工作中的案例深入地剖析了使用PL/SQL进行Oracle开发的方方面面。
本书附带1张DVD光盘,内容为作者为本书录制的全程语音教学视频及本书所涉及的源代码。
本书分为5大篇共20章。涵盖的内容主要有PL/SQL语言基础、开发环境、变量与类型、控制语句、数据表的管理和查询、数据表的操纵、使用PL/SQL的记录与集合、各种内置函数、游标、事务处理、异常处理、子程序、包、面向对象的开发等技术点。通过示例性的代码,由浅入深,详细介绍了每一个技术要点在实际工作中的应用,对各种技术要点的应用场合进行了细致的分析。
本书适合于使用PL/SQL进行应用程序开发的人员、对软件开发有兴趣的学生及爱好者阅读和参考;对数据库管理员、企业IT运维人员也具有很强的指导作用。
本书封面贴有清华大学出版社防伪标签,无标签者不得销售。
版权所有,侵权必究。侵权举报电话:010-62782989 13701121933
图书在版编目(CIP)数据
Oracle PL/SQL从入门到精通 / 丁士锋等编著. —北京:清华大学出版社,2012.6
ISBN 978-7-302-28103-0
Ⅰ. ①O… Ⅱ. ①丁… Ⅲ. ①关系数据库-数据库管理系统,Oracle Ⅳ. ①TP311.138
中国版本图书馆CIP数据核字(2012)第030492号
责任编辑:夏兆彦
封面设计:
责任校对:徐俊伟
责任印制:
出版发行:清华大学出版社
网 址:,
地 址:北京清华大学学研大厦A座 邮 编:100084
社 总 机:010-62770175 邮 购:010-62786544
投稿与读者服务:010-62776969,c-service@
质量反馈:010-62772015,zhiliang@
印 刷 者:
装 订 者:肖 米
经 销:全国新华书店
开 本:185mm×260mm 印 张:42.25 字 数:1055千字
(附DVD 1张)
版 次:2012年6月第1版 印 次:2012年6月第1次印刷
印 数:1~5000
定 价:25.00元
产品编号:045147-01
前 言
为什么要写这本书
随着计算机信息技术的飞速发展,数据存储已经成为很多公司越来越重视的问题。Oracle公司的数据库管理软件以其稳定、高效和灵活性,一直是各大企事业单位后台存储的首选。Oracle系统本身的复杂性,使得很多刚入门的开发人员不知从何入手,尽管Oracle公司提供了大量的文档,但是这些文档大多为英文版本,每个文档都偏重于某一技术细节,没有提供系统的、适合我国程序员思维的学习材料。
目前在市面上关于PL/SQL的图书并不是很多,特别是由国内程序员经验总结的图书更是寥寥无几。本书作者站在一线开发人员的视角,通过简洁轻松的文字,简短精练的示例代码,以力求让不同层次的开发人员尽快掌握Oracle数据库开发为主旨编写了本书,同时在本书最后还提供了两个实战项目,让开发人员能够通过项目学习PL/SQL开发,提高实际开发水平和项目实战能力。
本书有何特色
1.附带多媒体语音教学视频,提高学习效率
为了便于读者理解本书内容,提高学习效率,作者专门为每一章内容都录制了大量的多媒体语音教学视频。这些视频和本书涉及的源代码一起收录于配书光盘中。
2.涵盖PL/SQL语言的各种技术细节,提供系统化的学习思路
本书涵盖了PL/SQL语言在实际项目中需要重点掌握的所有方面,包含语言基础、开发环境、常量和变量的定义、基本的控制结构、基本的SQL操作知识(比如查询、插入、修改和删除)、记录和集合、游标、SQL的内置函数、事务处理、异常处理机制、子程序、包、触发器、面向对象的开发及动态SQL语句等知识点。
3.对PL/SQL开发的各种技术做了原理分析和实战体验
全书使用简洁质朴的文字,配以大量的插图,将一些难以理解的原理部分进行了重点剖析,让读者不仅知晓实现的原理,通过图形化的展现方式,更能加强对原理的理解,同时配以大量的示例对技术要点在实际工作中的应用进行了详解,让读者能尽快上手。
4.应用驱动,实用性强
对于每段示例代码,都进行了仔细的锤炼,提供了各种实际应用的场景,力求让应用开发人员将这些知识点尽快应用到实际的开发过程中。
5.项目案例典型,实战性强,有较高的应用价值
本书最后一篇提供了两个项目实战案例。这些案例来源于作者所开发的实际项目,具有很高的应用价值和参考性。而且这些案例分别使用不同的PL/SQL技术实现,便于读者融会贯通地理解本书中所介绍的技术。这些案例稍加修改,便可用于实际项目开发中。
6.提供完善的技术支持和售后服务
本书提供了专门的技术支持邮箱:bookservice2008@。读者在阅读本书过程中有任何疑问都可以通过该邮箱获得帮助。
本书内容及知识体系
第1篇 PL/SQL开发入门(第1~4章)
本篇介绍了Oracle的组成架构和PL/SQL开发的基础知识。主要包括Oracle体系结构、PL/SQL开发环境、PL/SQL的总体概览、常量和变量的定义,以及基本的PL/SQL控制 结构。
第2篇 PL/SQL开发基础(第5~12章)
本篇是PL/SQL进行实际开发时必备的基础知识,包含使用Oracle SQL语句对数据表的查询、操纵;各种Oracle数据库对象的管理,比如同义词和序列等;同时对PL/SQL的记录与集合、各种SQL内置函数、游标、事务处理、锁定以及PL/SQL异常处理机制进行了详细的介绍。
第3篇 PL/SQL进阶编程(第13~16章)
本篇讨论了PL/SQL模块化编程相关的子程序、包、触发器的使用,这部分是实际工作中需要努力巩固的知识点,同时介绍了本地动态SQL技术的使用。这一篇的知识点是每个PL/SQL程序员必备的技能,在介绍形式上通过辅以大量与实际场景相结合的代码,提升开发人员的实战经验。
第4篇 PL/SQL高级编程(第17~18章)
本篇的内容针对已经熟练掌握了前面几篇的内容的开发人员,在具有了一定的PL/SQL开发经验后,可以通过本篇的内容学习使用面向对象的思维来开发PL/SQL应用程序,同时对于PL/SQL开发过程中的一些性能优化的注意事项进行了示例详解(提升开发人员的实战经验)。
第5篇 PL/SQL案例实战(第19~20章)
本篇通过两个实际的项目案例,从需求分析、数据库表的设计、系统的总体规划开始,到包规范的定义、包体的具体实现,详细剖析一个PL/SQL的实现生命周期,通过对这两个案例的一步一步深入体验,能让开发人员立即上手开始进行PL/SQL项目的开发。同时对这两个案例稍加修改,就能应用到实际的项目开发中。
配书光盘内容介绍
为了方便读者阅读本书,本书附带1张DVD光盘,内容如下。
q 本书所有实例的源代码;
q 本书每章内容的多媒体语音教学视频;
q 免费赠送的Oracle入门教学视频。
适合阅读本书的读者
q 需要全面学习Oracle PL/SQL开发技术的人员;
q 数据库开发程序员;
q 应用程序开发人员;
q Oracle数据库管理人员;
q 希望提高项目开发水平的人员;
q 专业培训机构的学员;
q 软件开发项目经理;
q 需要一本PL/SQL案头必备查询手册的人员。
阅读本书的建议
q 没有Oracle PL/SQL基础的读者,建议从第1章顺次阅读并演练每一个示例。
q 有一定Oracle PL/SQL基础的读者,可以根据实际情况有重点地选择阅读各个技术要点。
q 对于每一个知识点和项目案例,先通读一遍有个大概印象,然后对于每个知识点的示例代码都在开发环境中操作一遍,加深对知识点的印象。
q 结合光盘中提供的多媒体教学视频再理解一遍,这样理解起来就更加容易,也会更加深刻。
本书作者
本书由丁士锋主笔编写。其他参与编写、资料整理和程序调试的人员有陈世琼、陈欣、陈智敏、董加强、范礼、郭秋滟、郝红英、蒋春蕾、黎华、刘建准、刘霄、刘亚军、刘仲义、柳刚、罗永峰、马奎林、马味、欧阳昉、蒲军、齐凤莲、王海涛、魏来科、伍生全、谢平、徐学英、杨艳、余月、岳富军、张健和张娜。在此一并表示感谢!
笔者写作本书虽然耗费了大量精力,力争消灭错误,但恐百密难免一疏。若您在阅读本书的过程中发现任何问题,或者有任何疑问,都可以随时提出,笔者将尽最大努力解决。联系邮箱:bookservice2008@。
编著者
第5章 管理数据表
数据库表是Oracle数据库存储中基本但重要的部分,许多其他的数据库对象,例如索引、视图都以表为基础。在开发人员使用关系型数据库管理数据时,实际上就是通过创建一个或多个表来实现存储、约束等功能。
5.1 创 建 表
表是Oracle存储数据的基本单元,表与现实世界中的对象具有对应关系,在设计数据表时,一般使用ER图来构造实体关系模型,ER图通常是对现实世界中的业务进行的建模。这些ER图在变成数据库对象时,最终要转换成表。
数据库表又可称为二维数据集合,表的结构由列(或字段)进行定义,列包含类型和一些约束信息,表行是这些列的数据,表中的行又称为记录,由一条记录来描述一个实例。
5.1.1 数据定义语言DDL
用来创建表的SQL语言称为数据定义语言DDL,DDL的英文全称是Data Definition Language,主要用来操纵Oracle数据库的结构。可以使用DDL语句定义、修改和删除在Oracle中存在的每种类型的对象。
数据定义语言主要由CREATE、ALTER与DROP 3个语句组成。
1.CREATE语句
CREATE语句用来创建数据库对象,比如要创建数据库、数据表、索引或子程序、触发器等,根据创建的数据库对象的类型的不同,具有多种不同的参数。
例如可以使用CREATE TABLE创建一个数据库表,在下一小节会详细介绍创建的语法,或者可以使用CREATE DATABASE创建数据库,一些常见的使用CREATE语句的创建语法如下所示。
CREATE INDEX:创建数据表索引。
CREATE PROCEDURE:创建存储过程。
CREATE FUNCTION:创建用户函数。
CREATE VIEW:创建视图。
CREATE TRIGGER:创建触发器。
例如要创建一个公司的员工记录表,可以使用CREATE TABLE,建表示例如代码5.1所示。
代码5.1 使用DDL语句创建数据表
CREATE TABLE company_emp
(
empno NUMBER(4) PRIMARY KEY NOT NULL, --员工工号
ename VARCHAR2(10 BYTE), --员工名称
job VARCHAR2(9 BYTE), --员工职位
mgr NUMBER(4), --所属经理
hiredate DATE, --雇佣日期
sal NUMBER(7,2), --员工工资
comm NUMBER(7,2), --员工描述
deptno NUMBER(2) --部门编码
)
从代码中可以看到,在CREATE TABLE语句中,定义了数据表的表列及Oracle数据表字段类型,该语句执行后,就可以在当前用户方案下面看到company_emp表。
2.ALTER语句
ALTER语句用来修改数据库对象,比如可以修改表、视图、索引、触发器的定义等,由于ALTER只需要修改数据库对象的局部,因此不需要定义完整的数据库对象参数,可以根据要修改的幅度来决定使用的参数,例如要向前面创建的表company_emp中添加一个名为description的列,可以使用如下的代码:
ALTER TABLE company_emp ADD description VARCHAR2(200) NULL;
--向company_emp添加表列
上述代码中使用ALTER TABLE语句,向company_emp表添加了一个名为description的字段,该字段的类型为VARCHAR2(200),允许NULL值。
下面的代码同样使用ALTER TABLE语句来移除description字段:
ALTER TABLE company_emp DROP COLUMN description;
上述代码中,使用了ALTER TABLE中的DROP COLUMN来移除description字段。
3.DROP语句
DROP语句主要用来移除数据库对象,比如可以移除表、视图、索引等数据库对象,只需要在DROP语句后面输入要移除的对象名称即可,是DDL语法中最简单的语句。
例如要移除company_emp这个数据表,可以使用如下的DROP语法:
DROP TABLE company_emp; --移除company_emp表
所有的DDL语句的一个必须牢记的特色就是每一条DDL语句都包含了一个隐式提交的事务语句,因此只要这些命令执行,系统就会向数据库提交更改,所有具有访问数据库对象权限的用户马上就可以看到DDL语句的执行效果。
%注意:在PL/SQL语句块中,不能直接使用DDL语句,可以通过动态SQL语句的形式来执行SQL命令。
5.1.2 CREATE TABLE语句
CREATE TABLE语句用来创建Oracle数据库表,创建数据库表最简单的形式是为CREATE TABLE语句指定一个表名称,然后是括号包含起来的字段名称和字段类型。例如要创建一个简单的名为workcenter的表,可以使用如下的语法,如代码5.2所示。
代码5.2 简单的CREATE TABLE用法
--创建表workcenter
CREATE TABLE workcenter --指定表名称
(
id int, --添加编号字段
name varchar2(200) --添加名称字段
)
默认情况下,CREATE TABLE会将表创建在当前的方案下,如果想在其他方案中创建数据表,那么可以使用“方案名.表名称”这样的语法。例如如果想在HR方案中创建workcenter数据表,可以使用如下的语法:
--创建表workcenter
CREATE TABLE hr.workcenter --指定表名称
(
id int, --添加编号字段
name varchar2(200) --添加名称字段
)
如果是使用scott用户登录,默认情况下是不能在hr方案之下创建表的,因此上述语句在执行时Oracle会触发ORA-01031异常。提示权限不足。Toad中的提示如图5.1所示。
图5.1 Toad错误提示窗口
通过使用如下所示的GRANT语句来为scott授予创建任何方案下的表、视图和过程。
GRANT CREATE ANY TABLE,
CREATE ANY VIEW,
CREATE ANY PROCEDURE
TO scott;
%注意:在Oracle中,DDL语句具有多种权限限制,一般只有具有管理员权限(DBA)才能建立数据库对象,不过通过GRANT和REVOKE语句,可以显式地为任何用户分配权限。
在为数据库表命名时,应该遵循Oracle数据库对象的标准命名规则,如下所示。
q 表名和列名必须是具有描述性名称的字符串,以字母开头,且长度必须在1~30个字符以内。
q 表名中只能包含字符A~Z、a~z、0~9、_(下划线)、$和#(这两个字符虽然合法,但并不建议使用)。
q 表名和列名不能与同一Oracle服务器用户拥有的其他对象重名。
q 表名和列名不能是Oracle服务器的保留字。
%注意:表名和列表都是不区分大小写的。
在CREATE TABLE语句的括号中,定义了列名,并使用Oracle内置的数据类型指定了列的类型,关于Oracle内置的数据类型,请参考本书第3章的内容。
除了指定列的类型之外,还可以使用列类型属性来指定列的基本约束,常用的列特性有如下3个。
q NOT NULL:指定列不接受NULL值,如果省略该值,列将允许接受NULL值。
q UNIQUE:指定存储在列中的每一个值都必须唯一。
q DEFAULT default_value:指定列的默认值。
例如下面的代码5.3使用CREATE TABLE语句创建了一个发票表invoices,使用了列类型属性来对列进行基本的约束。
代码5.3 使用列约束创建表
CREATE TABLE invoice
(
invoice_id NUMBER NOT NULL UNIQUE, --自动编号,唯一,不为空
vendor_id NUMBER NOT NULL, --供应商ID
invoice_number VARCHAR2(50) NOT NULL, --发票编号
invoice_date DATE DEFAULT SYSDATE, --发票日期
invoice_total NUMBER(9,2) NOT NULL, --发票总数
payment_total NUMBER(9,2) DEFAULT 0 --付款总数
)
上述代码通过对列属性的使用,使得一些列的值不能为NULL;一些列具有DEFALUT指定的默认值;而一些列的值必须在整个表的相同的列中唯一。
下面的语法是创建一个表的最基本的语法:
CREATE TABLE [schema_name.]table_name
(
column_name_1 data_type [column_attributes]
[,column_name_2 data_type [column_attributes]]...
[,table_level_constraints]
)
Oracle为表的创建提供了大量的参数,一些参数可能需要DBA来参与辅助设置,对于PL/SQL的开发人员来说,只需要了解这些基本的语法就可以完成很多的工作了。
为了创建表,必须深入理解业务实体的数据类别及数据存储的容量,Oracle内置了一系列的数据类型允许用户使用来创建一个表。在本书介绍PL/SQL数据类型时曾经介绍过,PL/SQL支持访问所有的Oracle数据类型,Oracle数据类型可分为标量、复合、引用和LOB4种类型,要了解数据类型的详细信息,可以参考本书3.2节对数据类型的介绍。
5.1.3 在设计器中创建表
如果是使用Toad、PL/SQL Developer或者是Oracle SQL Developer等工具,可以直接使用工具提供的设计器来创建表。
1.在Toad中建表
要使用Toad创建表,可以通过单击主菜单的“Database|Create|Table”菜单项,或者是进入Schema Browser数据库模式窗口后,选择表节点(Treeview模式)或者是表标签(Tab模式),从下拉菜单栏或工具栏中选择创建表向导,如图5.2所示。
常用的工具栏按钮
表列和数据类型
及基本约束定义
方案和表名
及表类型选择
图5.2 使用Toad的表创建向导
Toad提供了多种数据表类型可供选择,这些数据表类型具有各自不同的用处,本书主要介绍标准表的创建,有兴趣的读者可以参考Oracle文档获取其他类型的表的使用信息。
对于已创建的表,Toad提供了功能强大的表查看窗口,可以在查询语句或PL/SQL代码编辑器中将鼠标指针放在名称字符串中,使用F4键打开表查看窗口,或者在Toad的SQL编辑器中输入DESC 表名,将显示如图5.3所示的表查看窗口。
图5.3 表信息查看与修改窗口
使用这个功能强大的窗口,允许DBA或系统管理员随时查看与表相关的所有的信息,比如权限、触发器、约束及表数据等。
2.在PL/SQL Developer中创建表
与Toad类似,PL/SQL提供了表创建向导,可以通过单击“文件|新建|表”菜单项来打开如图5.4所示的表创建窗口。
图5.4 PL/SQL Developer表创建向导窗口
PL/SQL Developer的表创建向导使用Tab页的形式提供了创建表的多个选项,比如指定表的存储选项,表的类型,表的列、键、约束、索引等信息。
3.在Oracle SQL Developer中创建表
Oracle SQL Developer同样提供了所见即所得的数据表设计器窗口,可以通过导航面板的树状视图,展开数据库连接节点,右击数据表节点,选择“新建表...”菜单项,将显示如图5.5所示的表设计器窗口。
图5.5 Oracle SQL Developer创建表窗口
在创建表窗口中,可以通过“添加列”按钮添加新的列,从下拉列表框中选择列数据类型及约束,并可单击“DDL”标签页来查看创建表的数据定义语言。
5.1.4 创建表副本
CRETAE TABLE提供的AS SELECT语句,允许从一个现有的表中创建一个新的表,创建的表可以包含原表的所有架构、字段属性、约束和数据记录;也可以仅架构完全相同,而不包含数据,其使用语法如下所示。
CREATE TABLE <newtable> AS SELECT {* | column(s)} FROM <oldtable> [WHERE <condition>];
例如要创建scott方案下的emp表的副本并包含所有的数据,则可以使用如下的语句:
CREATE TABLE emp_copy AS SELECT * from scott.emp
可以使用下面的语法仅创建一个架构而不包含任何表数据:
CREATE TABLE emp_copy AS SELECT * from scott.emp WHERE 1=2;
上述代码中,复制的新表将与原来的表列具有完全相同的定义,但是可以通过改变查询SELECT语句,例如使用函数进行类型的转换等来创建不完全相同的类型,如以下代码所示。
CREATE TABLE emp_copy_others AS SELECT empno,ename,TO_CHAR(hiredate,'yyyy-
MM-dd') AS hiredate FROM scott.emp;
使用CREATE TABLE..SELECT AS方式有如下几个限制需要注意。
q 不能够复制约束条件与列的默认值,这需要手工重新建立。
q 不能够为新表指定表空间,默认情况下采用的是当前用户的默认表空间。
q 一些大对象数据类型(比如Blob类型)或者是Long数据类型的数据,如果包含这种类型的查询是不能创建成功的。
5.2 创 建 约 束
约束是一个或多个为了保证数据的完整性而实现的一套机制,约束是数据库服务器强制用户必须遵从的业务逻辑。它们限制用户可能输入指定范围的值,从而强制引用完整性。
约束可以定义在字段级别和表级别,根据约束的类别的不同指定约束定义的不同位置,在Oracle中最常使用的约束分为如下5类。
q 非空约束:验证字段的值不能为空,一般在字段级别使用NOT NULL列属性进行约束。
q 唯一约束:指定列的值在整个表的相同列中是唯一的,既可以在表级别也可以在字段级别定义,在字段级别使用UNIQUE进行声明。
q 检查约束:在定义数据库表时,在字段级别或在表级别加入检查约束,使其满足特定的要求,允许指定字段的检查条件,比如值大于0或小于0等。
q 主键约束:SQL 92建议在建立一个表时定义一个主键,它其实就是:唯一约束+非空约束。
q 外键约束:用于定义表间关联的约束,实现数据完整性,这是关系型数据库的 精髓。
约束可以在创建表的时候定义,也可以在建表之后使用ALTER语句添加和修改约束。
5.2.1 创建主键约束
当使用CREATE TABLE语句创建表时,列的NOT NULL和UNIQUE关键字都是表列的约束,这些约束限制了在列中可以存储的数据的类型,除此之外,还可以在列类型的后面使用PRIMARY KEY关键字指定列的类型为主键。当为列指定了主键后,列被强制为NOT NULL,并且列中的每行都被强制为一个唯一值,此外,会根据这个列自动地创建一个索引。
例如对于invoice这个表,可以使用如下的语法来创建并指定主键,如代码5.4所示。
代码5.4 创建invoice表并指定主键
CREATE TABLE invoice
(
invoice_id NUMBER PRIMARY KEY, --自动编号,唯一,不为空
vendor_id NUMBER NOT NULL, --供应商ID
invoice_number VARCHAR2(50) NOT NULL, --发票编号
invoice_date DATE DEFAULT SYSDATE, --发票日期
invoice_total NUMBER(9,2) NOT NULL, --发票总数
payment_total NUMBER(9,2) DEFAULT 0 --付款总数
)
%注意:如果invoice表已经存在,则使用DROP TABLE invoice语句将其删除重建。
代码中使用PRIMARY KEY关键字对invoice_id列进行修饰,表示将以invoice_id作为表的主键,这是最简单的指定表的主键的方式,但不是最好的编程习惯。
%注意:如果没有为约束指定名称,Oracle将使用SYS_Cn格式自动生成一个名称,其中n表示一个唯一性的整数,可以通过USER_CONSTRAINTS数据字典表来了解特定的表定义的约束。
建议的方法是在列或表级别使用CONSTRAINT关键字,为约束指定一个约束名,因而对于创建表的代码也可以使用如下的语法,如代码5.5使用了列级别的CONSTRAINT关键字来创建表。
代码5.5 在列属性中使用CONSTRAINT关键字
CREATE TABLE invoice
(
invoice_id NUMBER CONSTRAINT invoice_pk PRIMARY KEY,
--自动编号,唯一,不为空
vendor_id NUMBER CONSTRAINT vendor_id_nn NOT NULL, --供应商ID
invoice_number VARCHAR2(50) CONSTRAINT vendor_number_nn NOT NULL,
--发票编号
invoice_date DATE DEFAULT SYSDATE, --发票日期
invoice_total NUMBER(9,2) CONSTRAINT invoice_total_nn NOT NULL,
--发票总数
payment_total NUMBER(9,2) DEFAULT 0 --付款总数
)
通过将CONSTRAINT定义在列类型后面,可以显式地创建约束,并能为约束指定约束名称。对于UNIQUE与PRIMARY KEY,还可以在表级别使用CONSTRAINT指定约束,比如在为一个表设置多个主键时,可以在表级别使用CONSTRAINT设置约束。在表级别与在列级别的效果是相同的,但是能提供更清晰的代码,将代码5.5的CONSTRAINT声明更改为表级别,实现如代码5.6所示。
代码5.6 在表级别使用CONSTRAINT关键字
CREATE TABLE invoice
(
invoice_id NUMBER , --自动编号,唯一,不为空
vendor_id NUMBER, --供应商ID
invoice_number VARCHAR2(50), --发票编号
invoice_date DATE DEFAULT SYSDATE, --发票日期
invoice_total NUMBER(9,2) , --发票总数
payment_total NUMBER(9,2) DEFAULT 0, --付款总数
CONSTRAINT invoice_pk PRIMARY KEY (invoice_id),
CONSTRAINT vendor_id_un UNIQUE (vendor_id)
);
上述代码相对于列类型来说最大的好处在于可以使用多列,比如通过在括号内输入以逗号分隔的多个列名,可以同时指定多列主键,例如如果要使用invoide_id和vendor_id作为主键,可以使用如下所示的代码:
CONSTRAINT invoiceid_vendorid_pk PRIMARY KEY (invoice_id,vendor_id),
在为表设计主键时,下面是一些常用的设置规则。
q 主键应该是对用户没有意义的,在一些数据表的设计中,不建议以材料编码或身份证号码及员工工号作为主键,主键应该只是一些具有唯一性标识的标识符,比如自增长的数字等。
q 主键应该是单列的,以便提高连接和筛选操作的性能,复合主键通常导致不良的外键,因此要尽量避免。
q 主键应该是不能被更新的,主键的主要作用是唯一标识一行,更新则违反了主键无意义的原则。
q 主键不应该包含动态更新的数据,比如时间戳、创建时间或修改时间等这些动态变化的数据。
q 主键最好由计算机自动生成,在Oracle中可以使用序列来为主键列生成值。
5.2.2 创建外键约束
外键约束又称为引用约束,这种类型的约束主要用来在多个表之间定义关系,并强制引用完整性,与主键约束一样,外键约束也可以在列级别和表级别创建,使用关键字REFERENCES语句来定义,列级别的外键约束语法如下所示。
[CONSTRAINT constraint_name]
REFERENCES table_name (column_name)
[ON DELETE {CASCADE|SET NULL}]
位于[]的可选部分指定CONSTRAINT和约束名称,ON DELETE {CASCADE|SET NULL}这行代码用来指示是否级联删除,当两个表中的两个字段建立了外键关联后,如果主键所在表中的值被删除,使用ON DELETE指定是否级联删除,CASCADE表示关联表中的内容一并删除,而SET NULL表示子表中的值设置为NULL。
%注意:如果没有指定ON DELETE,默认情况下将使用CASCADE进行级联删除。
假定有一个表vendor,可以将invoice表的vendor_id与vendor表的vendor_id字段进行外键约束,也就是说,invoice表中的字段取值必须是vendor表中已经存在的供应商字段,vendor表的创建如代码5.7所示。
代码5.7 vendor表的定义代码
CREATE TABLE vendors
(
vendor_id NUMBER, --供应商id
vendor_name VARCHAR2(50) NOT NULL, --供应商名称
CONSTRAINT vendors_pk PRIMARY KEY (vendor_id), --主键
CONSTRAINT vendor_name_uq UNIQUE (vendor_name) --唯一性约束
)
下面的代码创建invoice表,在列级别为invoice表的vendor_id字段与vendor表的vendor_id字段进行了关联,如代码5.8所示。
代码5.8 在invoice表中为vendor_id列创建外键关联
CREATE TABLE invoice
(
invoice_id NUMBER , --自动编号,唯一,不为空
vendor_id NUMBER REFERENCES vendors (vendor_id), --供应商ID
invoice_number VARCHAR2(50), --发票编号
invoice_date DATE DEFAULT SYSDATE, --发票日期
invoice_total NUMBER(9,2) , --发票总数
payment_total NUMBER(9,2) DEFAULT 0, --付款总数
CONSTR
展开阅读全文