oracle 数据库开发应用实例,招生录取系统,oracle与plsql教程打包下载

系统分析和准备
概述
通过计算机完成高等院校的招生录取工作,是一个复杂而又有代表性的数据库应用。其中涉及到大量考生和院校数据的录入、整理、存储以及由数据库应用程序来实现录取过程的自动化等工作。因为在校学生对高考录取过程都有一定程度的了解,所以我们选用这一项目来达到综合运用Oracle数据库的训练目的。因为这个系统比较复杂,所以我们通过设计和实现一个简化的“招生录取系统”来模拟招生录取的过程。
系统首先要建立合理的数据结构和关系,并输入必要的基本数据,然后根据院校的招生要求和学生填报的志愿,实现对符合要求的考生的录取。通过对这一过程的模拟,我们可以比较全面地应用前面所学的知识和技能,并提高使用Oracle数据库技术解决实际问题的能力。
基本需求分析
先来做一个简单的需求分析。高考招生和录取工作,一般是由招生部门和院校合作完成的。招生部门和院校是该应用程序的使用者。该应用程序为考生只提供一些简单的查询功能。
1.院校
院校应提供招生的要求,如招生的人数、最低录取分数线以及对考生的其他条件的限制。
院校需要在录取结束后查询院校的录取名单。
2.招生部门
招生部门要收集和整理考生信息,建立考生信息库和院校信息库。考生信息库用于存取考生的基本信息,包括考生的高考成绩和报考志愿;院校信息库用于存取院校的基本信息和招生信息。
招生部门通过数据库中的院校信息和考生信息,由相应的数据库应用程序来完成一系列的数据加工处理过程,其中最主要的就是投档录取过程。所谓投档,就是把满足院校要求的考生档案信息发送给院校,由院校审查档案后决定考生的录取与否。为了简化录取过程,我们由系统投档程序来完成考生的录取工作,一旦考生满足院校招生条件,即视为被录取。被录取的考生,在数据库中要标识成录取状态,并记录录取院校的信息,在院校信息库中要回填录取人数的有关信息。
在录取过程中或录取结束后,招生部门要进行查询和统计,主要是在录取结束后统计所有院校的招生情况。
3.考生
考生在录取过程中需要查询其高考分数和录取状态。
10.1.3  功能分析设计
系统完成的主要功能有数据录入、投档和查询统计。
1.数据录入
数据录入要完成院校和学生信息表的数据输入及修改工作。
在本系统中,为了完成录取的模拟,可以虚拟10所院校,给出院校的基本信息和招生要求;虚拟至少50名考生,给出考生的基本信息以及考试成绩,并为每个考生填报2个院校志愿(一志愿和二志愿)。为了简化数据录入,可直接由SQL语句或其他工具完成,比如可以使用TOAD软件来完成。
2.投档过程
招生录取的原则是:一志愿要求优先录取,一志愿全部录取完毕后,才能开始二志愿的录取;二志愿录取对没有达到计划招生人数的院校进行补充录取。
根据以上原则,投档可分为一志愿投档和二志愿投档。一志愿投档是根据院校编号完成对一个学校的一志愿投档的;二志愿投档是根据院校编号完成对一个学校的二志愿投档的,二志愿投档应该在一志愿投档完成以后进行。一次完成全部院校的投档称为自动投档。自动投档一次完成对所有院校的一志愿或二志愿投档。如果使用自动投档,只需为一志愿和二志愿分别投档一次,即完成投档过程。作为补充,可以设计一个调剂投档功能,对一、二志愿没有被录取的考生,如果存在没有招满的院校,补充录取同意调剂的考生。
3.查询统计
在投档过程中或投档结束之后,根据院校编号显示院校的录取结果,即录取考生按分数排序的名单,同时应该显示考生的分数、录取的志愿等信息。
在录取结束之后,按院校的录取平均分数排名,显示所有院校的招生统计信息。
开发账户的创建和授权
在开发之前,要为新的应用创建模式账户,并授予必要的权限,以便创建表和其他数据库对象。为了能够创建账户和授权,必须使用具有足够权限的管理账户,可使用系统管理员账户来创建新的应用账户。
在users表空间上创建开发账户,增加一些权限。
步骤1:创建账户:
CREATE USER STUDENT IDENTIFIED BY STUDENT DEFAULT TABLESPACE USERS;
		步骤2:授予用户权限。
		连接数据库权限:
		
GRANT CONNECT TO STUDENT;

创建表权限:
GRANT CREATE TABLE TO STUDENT;

创建视图权限:
GRANT CREATE VIEW TO STUDENT;

创建序列权限:
GRANT CREATE SEQUENCE TO STUDENT;

创建同义词权限:
GRANT CREATE SYNONYM TO STUDENT;

创建存储过程、函数权限:
GRANT CREATE PROCEDURE TO STUDENT;

创建触发器权限:
GRANT CREATE TRIGGER TO STUDENT;

表空间使用权限:
GRANT UNLIMITED TABLESPACE TO STUDENT;

步骤3:使用新账户登录:
CONNECT STUDENT/STUDENT@MYDB;

  至此,已经做好了使用STUDENT账户进行开发的准备。
表和视图的设计和实现
院校信息表
1.院校信息表结构设计
名称:COLLEGE。
字段结构如下所示。
字段名称	类  型	宽  度	约束条件	简要说明
院校编号	number	4	主键	院校的编号
院校名称	varchar2	30	不允许为空	院校的名称
录取分数线	number	3	在300~700之间	院校最低录取控制分数线
招生人数	number	3	<=10 	计划招生总人数
录取人数	number	3	默认初值为0	已经录取的人数

字段含义说明:
院校编号:为该表的主键,是从1001开始的4位数。
院校名称:院校的全称,必须填写。
录取分数线:是院校确定的考生最低录取分数线,低于录取分数线的考生不能被录取。
招生人数:是院校计划招生的人数。
录取人数:在某院校录取过程中回填的已经被录取的一、二志愿人数的和。当录取人数等于招生人数时录取结束。
有关数值型数据的范围限定可以通过添加约束条件实现。
2.表的创建
使用以下脚本创建院校信息表COLLEGE:
CREATE TABLE COLLEGE(
		院校编号 NUMBER(4) PRIMARY KEY,
		院校名称 VARCHAR2(30) NOT NULL,
		录取分数线 NUMBER(3) CHECK(录取分数线 BETWEEN 300 AND 700),
		招生人数 NUMBER(3) CHECK(招生人数 <= 10),
		录取人数 NUMBER(3) DEFAULT 0
		);

3.数据的插入
使用以下脚本插入虚拟的10所院校数据:
INSERT INTO COLLEGE VALUES(1001,'清华大学',620,5,0);
	INSERT INTO COLLEGE VALUES(1002,'北京大学',600,4,0);
	INSERT INTO COLLEGE VALUES(1003,'武汉大学',550,6,0);
	INSERT INTO COLLEGE VALUES(1004,'华南科技大学',530,3,0);
	INSERT INTO COLLEGE VALUES(1005,'复旦大学',580,4,0);
INSERT INTO COLLEGE VALUES(1006,'中山大学',560,5,0);
	INSERT INTO COLLEGE VALUES(1007,'华南理工大学',520,4,0);
	INSERT INTO COLLEGE VALUES(1008,'暨南大学',510,3,0);
	INSERT INTO COLLEGE VALUES(1009,'深圳大学',500,6,0);
	INSERT INTO COLLEGE VALUES(1010,'深圳职业技术学院',450,8,0);
	COMMIT;

说明:以清华大学为例,院校编号为1001,录取分数线为620,招生人数为6,已录取人数初值为0。
注意:插入的数据如果违反约束条件就会发生错误。
4.检查插入的数据
使用以下查询命令检查插入结果:
SELECT * FROM college;

执行结果略。
学生信息表
1.学生信息表的设计
名称:STUDENT。
字段结构如下所示。
字段名称	类  型	宽度	约束条件	简要说明
编号	number	5	主键	考生的编号
姓名	varchar2	15	不允许为空	考生的姓名
性别	varchar2	1	1-男,2-女	考生的性别编码
总分	number	3	<=700	考生高考总分
同意调剂	varchar2	1	默认为0	是否同意调剂,0-不同意,1-同意
一志愿	number	4	外键,参照COLLEGE表的院校编号	一志愿的院校编号
二志愿	number	4	外键,参照COLLEGE表的院校编号	二志愿的院校编号
录取状态	varchar2	1	默认为0	状态,0-未录取,1-录取
录取院校	number	4	外键,参照COLLEGE表的院校编号	录取院校的编号
录取志愿	varchar2	1	默认为空	表示考生被哪个志愿录取,1-代表一志愿,2-代表二志愿,3-代表调剂
录取日期	data		默认为空	录取的日期
操作人	varchar2	10	默认为空	对考生投档的账户

字段含义说明:
编号:为该表主键,是从10001开始的5位数值,可以使用序列自动填充。
学生性别:只能是1或2,1代表男,2代表女,使用约束条件控制。
   总分:为高考的总分数,约束条件是小于等于700分,假定满分为700分。
同意调剂:默认值为0,表示不同意调剂,值为1代表同意调剂。同意调剂的考生,在一志愿、二志愿录取结束后,可以参加调剂录取。
一志愿:为考生填写的一志愿院校的编号。该字段参照院校表(COLLEGE)的院校编号。
二志愿:为考生填写的二志愿院校的编号。该字段参照院校表(COLLEGE)的院校编号。
录取状态:默认为0,代表没有录取,录取时改为1,代表已经录取。
录取院校:默认为空,在录取时填入录取院校的编号。该字段参照院校表(COLLEGE)的院校编号。
录取志愿:为1、2或3,代表考生被录取的志愿,1代表一志愿录取,2代表二志愿录取,3代表通过调剂被录取。
录取日期:默认为空,在考生被录取时,填入系统时间。
操作人:默认为空,在考生被录取时,填入投档账户名。
有关数值型数据的范围限定可以通过添加约束条件实现。
2.表的创建
以下脚本创建考生信息表STUDENT:
CREATE TABLE STUDENT(
		编号 NUMBER(5) PRIMARY KEY,
		姓名 VARCHAR2(15) NOT NULL,
		性别 VARCHAR2(1) CHECK(性别 IN('1','2')),
		总分 NUMBER(3) CHECK(总分<=700),
		同意调剂 VARCHAR2(1) DEFAULT '0',
一志愿 NUMBER(4),
		二志愿 NUMBER(4),
		录取状态 VARCHAR2(1) DEFAULT '0',
		录取志愿 VARCHAR2(1) DEFAULT NULL CHECK(录取志愿 IN('1','2', '3')),
		录取院校 NUMBER(4) DEFAULT NULL,
		录取日期 DATE,
		操作人 VARCHAR2(10),
		CONSTRAINT FK_1 FOREIGN KEY (一志愿) REFERENCES COLLEGE(院校编号),
CONSTRAINT FK_2 FOREIGN KEY (二志愿) REFERENCES COLLEGE(院校编号),
		CONSTRAINT FK_3 FOREIGN KEY (录取院校) REFERENCES COLLEGE(院校编号)
		);

3.数据的插入
在插入数据中使用序列,可自动生成考生编号。
步骤1:创建序列STUNO_SQU:
CREATE SEQUENCE STUNO_SQU 
    		 START WITH 10001 
     		INCREMENT BY 1
     		NOCACHE
    		 NOCYCLE;

步骤2:使用以下脚本插入50名虚拟考生数据:
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES (STUNO_SQU.NEXTVAL, '陈文政','1',598,1010,1001,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,'李敏','2',460,1009,1010,'1');

		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES(STUNO_SQU.NEXTVAL,
			'黄宾','1',627,1001,1002,'0');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL
		'张晓羽','2',615,1002,1003,'1');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'许小猛','1',534,1008,1009,'0');
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		‘杨煌’,‘1’,555,1005,1007,‘0’);
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'陈丽明','2',587,1006,1008,'0');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'尹文哲','1',455,1004,1010,'1');
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'段然','1',325,1010,1006,'1');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'袁慧瑶','2',477,1009,1010,'0');
?		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'罗卓群','2',367,1003,1008,'1');
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'张婷','2',665,1001,1009,'0');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'李婷','2',585,1002,1003,'1');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL,'林树金','1', 600,1005,1006,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		‘吴岳’,‘2’,525,1009,1010,‘0’);
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'周易','2',485,1010,1009,'0');
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,'罗惯通','1',585,1007,1008,'1');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,'石海林','2',555,1005,1009,'0');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES(STUNO_SQU.NEXTVAL,
		'李旋','2',595,1002,1004,'1');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		‘张建锋’,‘1’,688,1001,1002,‘0’);
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES(STUNO_SQU.NEXTVAL,
		'何健飞','1',689,1001,1002,'0');
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL, '徐子钊','1', 600,1001,1003,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, ‘张庆旭’,‘1’, 490,1008,1010,‘1’); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '张蜡','1', 502,1008,1009,'1'); 
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, ‘李香’,‘2’, 600,1003,1004,‘0’); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '陈衬欢','2', 300,1009,1010,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL, '胡笛','2', 610,1001,1002,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, ‘舒娜’,‘2’, 560,1003,1004,‘0’); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '普伟','1', 519,1004,1009,'1'); 
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '国丹丹','2', 415,1009,1010,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '李冠军','1', 610,1005,1007,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL, '郭亚军','1', 588,1004,1006,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '陈兵','1', 498,1010,1008,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '洪智力','1', 378,1003,1005,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '李丽','2', 609,1002,1006,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '吴子俊','1', 600,1002,1005,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL, '黄炎炎','1', 507,1009,1008,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '黄源源','2', 540,1008,1010,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '曹万吉','2', 617,1003,1004,'0'); 
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, ‘谢敏’,‘2’, 348,1005,1006,‘1’); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '林晨曦','1', 532,1007,1008,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
VALUES( STUNO_SQU.NEXTVAL, '邓树林','2', 485,1002,1009,'0'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, ‘邱雨林’,‘2’, 608,1006,1008,‘0’); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '唐文文','1', 582,1008,1009,'0');
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '张韦','2', 555,1005,1007,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '胡月','2', 557,1007,1009,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '高飞云','2', 540,1005,1006,'0'); 
INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '陆文浩','1', 550,1006,1010,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '孙庆','2', 630,1001,1002,'1'); 
		INSERT INTO STUDENT(编号,姓名,性别,总分,一志愿,二志愿,同意调剂) 
		VALUES( STUNO_SQU.NEXTVAL, '王聪','1', 605,1003,1004,'0'); 
		COMMIT;

说明:以第二个考生为例:编号由序列生成,为10002;姓名李敏;性别为2,表示女;总分460;一志愿1009,即深圳大学;二志愿1010,即深圳职业技术学院。其他字段取默认值。参照表10-2,则录取状态默认为0,表示未录取。
注意:插入的数据如果违反约束条件就会发生错误。
  经检查发现考生10045的成绩输入错误,不是555而应该为553,通过以下查询予以修改。
UPDATE STDUENT SET 总分=553 WHERE 编号=10045;
		COMMIT;

执行结果:
已更新 1 行。
		提交完成。

4.检查插入的数据
使用以下查询检查插入的数据:
SELECT * from STUDENT

执行结果略。
  5.通过联合查询检查考生的志愿
由于填报志愿时,考生信息表中填写的是院校编号,需要通过相等连接才能显示院校名称。以一志愿为例,显示考生姓名和报考的一志愿院校名称:
SELECT 姓名,总分,院校名称 FROM student s,college c WHERE s.一志愿=c.院校编号;

执行结果:
姓名                  总分 院校名称
		------------------------------ ---------- ------------------------------
陈文政                 598 深圳职业技术学院
		李敏                   460 深圳大学
		黄宾                   627 清华大学
		张晓羽                 615 北京大学
		许小猛                 534 暨南大学
		杨煌                   555 复旦大学
		陈丽明                 587 中山大学
		尹文哲                 455 华南科技大学
		段然                   325 深圳职业技术学院
		袁慧瑶                 477 深圳大学

创建视图
一旦建立视图,通过直接对视图进行查询而不是对基表进行查询,可以实现对数据的保护,并简化操作。同时可建立视图的同义词,用于为复杂对象名生成一个简化和便于记忆的别名。考虑建立如下所示的视图。
序  号	视图名称	同义词	作  用
1	考生成绩	SCORE	查看学生的成绩
2	录取考生	RESULT	查看已录取考生
3	录取情况	STATUS	查看录取没有完成的院校

1.考生成绩视图
基表:STUDENT。
结构:考生成绩(编号,姓名,总分),只读视图。
功能:为了方便查看学生的成绩,建立学生成绩视图,显示全部学生的考号、姓名和成绩。
步骤1:创建视图:
CREATE OR REPLACE VIEW 考生成绩(编号,姓名,总分)
		AS SELECT 编号,姓名,总分 FROM student 
		WITH READ ONLY;

步骤2:生成考生成绩视图的同义词score:
CREATE SYNONYM SCORE FOR 考生成绩;

2.录取考生视图
基表:STUDENT和COLLEGE。
结构:录取考生(编号,姓名,院校名称),条件是只显示录取的考生信息,只读视图。需要通过建立相等连接来实现。
功能:为了方便查看学生的录取结果,建立录取学生的视图,显示被录取学生的考号、姓名和录取院校名称。
步骤1:建立视图:
CREATE OR REPLACE VIEW 录取考生(编号,姓名,录取院校名称)
		AS SELECT 编号,姓名,院校名称 FROM student,college
		WHERE 录取状态='1' AND student.录取院校=college.院校编号 
		WITH READ ONLY;

步骤2:生成录取考生视图的同义词RESULT:
CREATE SYNONYM RESULT FOR 录取考生;

3.录取情况视图
基表:COLLEGE。
结构:录取情况(院校编号,院校名称,状态,招生人数,缺额),只读视图。
功能:显示招生计划完成情况,计划招生人数和录取的缺额。
步骤1:创建视图:
CREATE OR REPLACE VIEW 录取情况(院校编号,院校名称,状态,招生人数,缺额) 
		AS SELECT 院校编号,院校名称,DECODE(SIGN(招生人数-录取人数),1,'未完成','完成'),招生人数,招生人数-录取人数 
		FROM college  WITH READ ONLY;

步骤2:生成录取情况视图的同义词STATUS:
CREATE SYNONYM STATUS FOR 录取情况;

  说明:SIGN函数返回算术运算结果的符号,结果大于0返回1,等于0返回0,小于0返回-1。如果招生人数大于录取人数,则表达式SIGN(招生人数-录取人数)的结果为1。此时,DECODE函数返回“未完成”;否则返回“完成”。
应用程序的设计和实现
函数的创建
首先要建立一些函数,以便其他模块或查询引用。设计如下所示的函数。
序号	函数名称	作   用
1	GET_STUDENT_NAME	通过考号获得考生姓名,如不存在,则返回“无”
2	GET_SCORE	通过考号获得考生成绩,如不存在,则返回-1
3	GET_COLLEGE_NAME	通过院校编号获得院校名称,如不存在,则返回“无”

1.返回考生姓名函数GET_STUDENT_NAME
函数名和参数:GET_STUDENT_NAME(P_BH)。
该函数的返回值类型为VARCHAR2。其中,P_BH代表考生编号。
功能:通过考生的编号获得考生的姓名。
返回考生名称函数如下:
 
CREATE OR REPLACE FUNCTION GET_STUDENT_NAME(P_BH NUMBER)
		RETURN VARCHAR2
AS
 		 V_NAME VARCHAR2(10);
		BEGIN
 		 SELECT 姓名 INTO V_NAME FROM STUDENT WHERE 编号=P_BH;
  		RETURN(V_NAME);
		EXCEPTION
		WHEN OTHERS THEN
  		 RETURN('无');
		END;

2.返回考生成绩函数GET_SCORE
函数名和参数:GET_SCORE(P_BH)。
该函数的返回值类型为NUMBER。其中,P_BH代表考生编号。
功能:通过考生的编号获得考生的总分。
返回考生成绩函数如下:
CREATE OR REPLACE FUNCTION GET_SCORE (P_BH NUMBER)
		RETURN NUMBER
		AS
V_SCORE NUMBER(3);
		BEGIN
		  SELECT 总分 INTO V_SCORE FROM SCORE WHERE 编号=P_BH;
  		RETURN (V_SCORE);
		EXCEPTION 
		 WHEN OTHERS THEN
 		 RETURN(-1);
		END;

  注意:分数直接从考生成绩视图中取得,SCORE为考生成绩视图的同义词。
3.返回院校名称函数GET_COLLEGE_NAME
函数名和参数:GET_COLLEGE_NAME(P_BH)
该函数的返回值类型为VARCHAR2。其中,P_BH代表院校编号。
功能:通过院校的编号获得院校名称。
返回院校名称函数如下:
 
CREATE OR REPLACE FUNCTION GET_COLLEGE_NAME (P_BH NUMBER)
		RETURN VARCHAR2  
AS
  		V_NAME VARCHAR2(30);
		BEGIN
  		SELECT 院校名称 INTO V_NAME FROM COLLEGE WHERE 院校编号=P_BH;
  		RETURN (V_NAME);
		EXCEPTION 
		 WHEN OTHERS THEN
 		 RETURN('无');
		END;

存储过程的创建
系统的功能通过存储过程来完成。考虑建立如下所示的存储过程。
 序号	过程名称	作    用
1	INPUT_COLLEGE	输入院校记录到院校表
2	INPUT_STUDENT	输入考生记录到考生表
3	CLEARSTATUS	初始化、清除考生录取状态
4	PROC1	一志愿投档
5	PROC2	二志愿投档
6	AUTOPROC	自动投档
7	SHOW_SCORE	查询考生分数
8	SHOW_RESULT	查询考生录取状态
9	STUDENT_LIST	院校录取考生列表
10	COLLEGE_TOTAL	统计院校录取信息

1.插入院校存储过程INPUT_COLLEGE
过程名和参数:
INPUT_COLLEGE(P_YXBH,P_YXMC,P_LQFSX,P_ZSRS)
其中,P_YXBH代表院校编号,P_YXMC代表院校名称,P_LQFSX表示录取分数线,P_ZSRS表示招生人数。
功能:该过程用于建立院校信息。每次执行时插入一个院校,部分字段的内容通过参数传递,没有指定参数的字段取字段的默认值。
插入院校程序如下:
步骤1:输入和调试以下存储过程:
CREATE OR REPLACE  PROCEDURE INPUT_COLLEGE 
		(V_YXBH IN NUMBER,V_YXMC IN VARCHAR2,V_LQFSX IN NUMBER,V_ZSRS IN NUMBER)
		AS 
 		R NUMBER;
		BEGIN
SELECT COUNT(*) INTO R FROM COLLEGE WHERE 院校编号=V_YXBH;
 		IF R>0 THEN 
 		 DBMS_OUTPUT.PUT_LINE('院校'||V_YXBH||'已经存在!');
 		ELSE
		 INSERT INTO COLLEGE
 		 VALUES(V_YXBH,V_YXMC,V_LQFSX,V_ZSRS,0);
 		 COMMIT;
 		 DBMS_OUTPUT.PUT_LINE('院校'||V_YXMC||'插入成功!');
 		END IF;
EXCEPTION
 		WHEN OTHERS THEN
 		DBMS_OUTPUT.PUT_LINE('院校'||V_YXMC||'插入失败!');
		END;
		步骤2:执行该存储过程:
		EXECUTE INPUT_COLLEGE(1011,'吉林大学',570,6);

执行结果:
院校吉林大学插入成功!
		PL/SQL 过程已成功完成。

  说明:如果院校编号已经存在,则提示不能插入。通过存储过程插入考生,可以正确显示插入过程的错误信息。
2.插入考生存储过程INPUT_STUDENT
过程名和参数:
INPUT_STUDENT (P_KSXM,P_XB,P_ZF,P_TYTJ,P_ZY1,P_ZY2)

其中,P_KSXM代表考生姓名,P_XB代表考生性别,P_ZF代表考生高考分数,P_TYTJ代表是否同意调剂,P_ZY1代表考生报考的一志愿院校编号,P_ZY2代表考生报考的二志愿院校编号。
功能:该过程用于输入考生信息。每次执行时插入一个考生,部分字段的内容通过参数传递,没有指定参数的字段取字段的默认值,考生编号取自序列。
程序略,可以参照插入院校过程。
3.投档初始化过程CLEARSTATUS
过程名和参数:
CLEARSTATUS
功能:该过程用于在每次开始模拟录取前对考生和院校表进行状态初始化。具体功能包括:清空COLLEGE表的录取人数;设置STUDENT表所有考生的录取状态为0(未录取),录取院校为空,录取志愿为空,录取日期为空,操作人为空。
初始化程序如下:
CREATE OR REPLACE PROCEDURE CLEARSTATUS
		AS 
		BEGIN
UPDATE COLLEGE SET 录取人数=0;
		 UPDATE STUDENT SET 录取状态=0,录取志愿=NULL,录取院校=NULL,录取日期=NULL,操作人=NULL;
 		COMMIT;
		END;

4.一志愿投档存储过程PROC1
过程名和参数:
PROC1(P_YXBH)
其中,参数P_YXBH代表要进行一志愿投挡的院校编号。
功能:该过程完成按照院校的要求对某院校进行一志愿投档录取的过程。投档时要指定院校编号作为参数。
投档过程是:对一志愿报考该院校的、分数在最低录取分数线上的学生,按分数进行排序,根据招生人数取前几名录取。
本次录取的考生要回填状态和录取院校等信息,将考生信息表中录取状态改为录取,并将院校编号和录取志愿号(为1)填入考生表。同时将院校信息表中对应的录取人数做相应的修改,将实际录取的人数回填院校表的录取人数字段。
说明:如果录取没有达到招生人数,将由二志愿来补充。该过程一次完成一个院校的投档。要一次完成所有院校的投档,可使用后面的自动投档存储过程。
一志愿投档程序如下:
CREATE OR REPLACE PROCEDURE PROC1(P_YXBH NUMBER)
		AS
		 V_ZSRS NUMBER(3);
		 V_LQFSX NUMBER(3);
 		V_YXMC VARCHAR2(30);
 		V_COUNT NUMBER(3);
		 CURSOR STU_CURSOR IS SELECT * FROM STUDENT 
 		WHERE 一志愿=P_YXBH ORDER BY 总分 DESC;
		BEGIN
SELECT 招生人数,录取分数线,院校名称 INTO V_ZSRS,V_LQFSX,V_YXMC 
 		 FROM COLLEGE WHERE 院校编号=P_YXBH;--取院校信息
 		 V_COUNT:=0;
 		 DBMS_OUTPUT.PUT_LINE('院校名称:'||V_YXMC||'一志愿投档开始');
  		DBMS_OUTPUT.PUT_LINE('--------------------- ----------------------------');
		  FOR STU_REC IN STU_CURSOR LOOP
		   EXIT WHEN V_COUNT>=V_ZSRS;
  		 IF(STU_REC.总分>=V_LQFSX) THEN
UPDATE STUDENT SET 录取状态='1',录取志愿='1',录取院校=P_YXBH,录取日期=SYSDATE,
		操作人=USER WHERE 编号= STU_REC.编号;
  		 DBMS_OUTPUT.PUT_LINE(' 编号:'|| STU_REC.编号||' 姓名:'||STU_REC.姓名||' 总分:'|| STU_REC.总分);
	V_COUNT:=V_COUNT+1;
		   END IF;    
  		END LOOP;
 		 DBMS_OUTPUT.PUT_LINE('------------------------------------------------------------');
UPDATE COLLEGE SET 录取人数=V_COUNT WHERE 院校编号=P_YXBH;
  		COMMIT;
		END;

  说明:该过程按院校进行一志愿投档,游标定义了一志愿报考该院校的按总分从高到低排序的所有考生信息。V_COUNT记录录取的人数,初值为0,每当录取一个考生,则加1。若V_COUNT等于计划招生人数,则结束录取。如果V_COUNT小于招生人数,则取游标的下一个考生,判断其分数是否在该院校的最低录取分数线之上。如果满足,则标记录取状态为1。录取结束后,将录取人数V_COUNT回填到院校表。
5.二志愿投档存储过程PROC2
过程名和参数:
PROC2(P_YXBH)
其中,参数P_YXBH代表要进行二志愿投档的院校编号。
功能:该过程完成按照院校的要求对某院校进行二志愿投档和录取的过程。投档时要指定院校编号作为参数。
过程是:对二志愿报考该院校且还没有录取的(去掉一志愿录取的考生)、分数在最低录取分数线上的学生,按分数进行排序,根据缺额(招生人数去掉录取人数)取前几名录取。
本次录取的考生要回填状态和录取院校等信息,将考生信息表中录取状态改为录取,并将院校编号、录取志愿号(为2)填入考生表。同时将院校信息表中对应的录取人数做相应的修改,将实际录取的人数回填院校表的录取人数字段。
说明:如果没有达到招生人数,将由调剂录取来补充。该过程一次完成一个院校的投档。要一次完成所有院校的投档,可使用后面的自动投档存储过程。
二志愿投档程序如下:
CREATE OR REPLACE PROCEDURE PROC2(P_YXBH NUMBER)
		AS
		 V_ZSRS NUMBER(3);
		 V_LQFSX NUMBER(3);
		 V_YXMC VARCHAR2(30);
		 V_LQRS NUMBER(3);
		 V_COUNT NUMBER(3);
		 CURSOR STU_CURSOR IS 
SELECT * FROM STUDENT 
		 WHERE 二志愿=P_YXBH AND 录取状态=0
		 ORDER BY 总分 DESC;
		BEGIN
  		SELECT 招生人数,录取分数线,录取人数,院校名称 INTO V_ZSRS,V_LQFSX,V_LQRS,V_YXMC 
  		FROM COLLEGE WHERE 院校编号=P_YXBH;
  		V_COUNT:=V_LQRS;
  		DBMS_OUTPUT.PUT_LINE('院校名称:'||V_YXMC||'二志愿投档开始');
DBMS_OUTPUT.PUT_LINE('------------------------------ -------------------');
  		FOR STU_REC IN STU_CURSOR LOOP
   		EXIT WHEN V_COUNT>=V_ZSRS;
  		 IF(STU_REC.总分>=V_LQFSX) THEN
   UPDATE STUDENT SET 录取状态='1',录取志愿='2',录取院校=P_YXBH,录取日期=SYSDATE,
		操作人=USER WHERE 编号= STU_REC.编号;
DBMS_OUTPUT.PUT_LINE(' 编号:'|| STU_REC.编号||' 姓名:'||STU_REC.姓名||' 总分:'|| STU_REC.总分);
	V_COUNT:=V_COUNT+1;
		   END IF;    
  		   END LOOP;
		DBMS_OUTPUT.PUT_LINE('------------------------------------------------------------');
		  UPDATE COLLEGE SET 录取人数=V_COUNT WHERE 院校编号=P_YXBH;
 		 COMMIT;
		END;

说明:该过程按院校进行二志愿投档,游标定义了二志愿报考该院校且录取状态为0(未录取)的、按总分从高到低排序的所有考生信息。V_COUNT记录录取的人数,初值为一志愿已经录取的人数,每当录取一个考生,则V_COUNT加1。若V_COUNT等于计划招生人数,则结束录取。如果V_COUNT小于招生人数,则取游标的下一个考生,判断其分数是否在该院校的最低录取分数线上。如果满足,则标记录取状态为1。录取结束后,将录取人数V_COUNT回填到院校表。
6.自动投档程序AUTOPROC
过程名和参数:
AUTOPROC(P_LQZY)
其中,P_LQZY代表要进行录取的志愿,只能是1或2,1代表一志愿,2代表二志愿。
功能:该过程根据选定志愿,循环对所有院校进行投档,即对所有院校循环调用PROC1或PROC2。一次完成所有院校的一志愿或二志愿投档。
自动投档程序如下:
CREATE OR REPLACE PROCEDURE AUTOPROC(P_LQZY NUMBER)
		AS
 		CURSOR COLLEGE_CURSOR IS SELECT 院校编号 FROM COLLEGE;
		BEGIN
 		 FOR COLLEGE_REC IN COLLEGE_CURSOR 	LOOP
   		IF (P_LQZY=1) THEN
     		PROC1(COLLEGE_REC.院校编号);
ELSIF (P_LQZY=2) THEN
   	 	PROC2(COLLEGE_REC.院校编号);
   		END IF;    
  		END LOOP;
		END;

  说明:定义一个取所有院校编号的游标COLLEGE_CURSOR,根据志愿(参数为1或2),在游标循环中以取得的院校编号为参数,调用一志愿或二志愿投档过程。
7.查询考生分数过程SHOW_SCORE
过程名和参数:
SHOW_SCORE(P_BH)
其中,P_BH代表考生编号。
功能:给出考生的考号,返回考生的高考成绩。
查询考生分数程序如下:
CREATE OR REPLACE PROCEDURE SHOW_SCORE(P_BH NUMBER)
		AS
V_SCORE NUMBER(3);
		BEGIN
		V_SCORE:= GET_SCORE(P_BH); 
 		IF V_SCORE=-1 THEN 
 		 DBMS_OUTPUT.PUT_LINE('考生编号错误!');
 		ELSE
  		DBMS_OUTPUT.PUT_LINE(''||GET_STUDENT_NAME(P_BH)||'总分'||V_SCORE);
 		END IF;
		END;

  说明:本过程调用返回考生姓名和分数的函数GET_STUDENT_NAME和GET_SCORE。
8.查询考生录取状态过程SHOW_RESULT
过程名和参数:
SHOW_RUSULT(P_BH)
其中,P_BH代表考生编号。
功能:给出考生的考号,返回录取院校名称。如果没有录取,则返回“未被录取”。
查询考生录取状态程序如下:
CREATE OR REPLACE PROCEDURE SHOW_RESULT(P_BH NUMBER)
AS
 		 V_LQYXMC VARCHAR2 (20);
 		 V_XM VARCHAR2(10);
		BEGIN
 		 V_XM:= GET_STUDENT_NAME(P_BH);
 		 IF V_XM = '无' THEN 
		   DBMS_OUTPUT.PUT_LINE('考生编号错误!'); 
 		 ELSE
		   SELECT 录取院校名称 INTO V_LQYXMC 		FROM RESULT WHERE 编号=P_BH;
DBMS_OUTPUT.PUT_LINE('考生'||V_XM||'被'||V_LQYXMC||'录取!');
 		 END IF; 
		EXCEPTION 
  		WHEN OTHERS THEN 
  		DBMS_OUTPUT.PUT_LINE('考生'|| V_XM ||'未被录取!');
		END;

  说明:查询录取考生视图RESULT,如果考生在视图中不存在,则表示未被录取。此过程中调用了前面定义的函数GET_STUDENT_NAME以获得考生名称。
9.显示院校录取名册存储过程STUDENT_LIST
过程名和参数:
STUDENT_LIST(P_YXBH)
其中,P_YXBH表示院校编号。
功能:指定院校编号,显示按分数排序的统计报表:
CREATE OR REPLACE PROCEDURE STUDENT_LIST(P_YXBH NUMBER)
		AS
		 V_SNAME VARCHAR2(10);
		 V_MAX NUMBER(3);
 		V_MIN NUMBER(3);
COL_REC COLLEGE%ROWTYPE;
 		CURSOR STU_CURSOR IS SELECT * FROM STUDENT WHERE 录取院校=P_YXBH ORDER BY 总分 DESC;
		BEGIN
 		 SELECT * INTO COL_REC FROM COLLEGE WHERE 院校编号=P_YXBH;
		DBMS_OUTPUT.PUT_LINE(GET_COLLEGE_NAME(P_YXBH)||'院校录取统计表');
  		DBMS_OUTPUT.PUT_LINE(' 招生人数:'||COL_REC.招生人数||'  录取人数:'||COL_REC.录取人数||'  录取分数线:'||COL_REC.录取分数线);
DBMS_OUTPUT.PUT_LINE('----------------------------------------------------------------------')
		DBMS_OUTPUT.PUT_LINE('序号    考生编号  姓名    性别   总分   录取志愿  录取日期');
 		 FOR STU_REC IN STU_CURSOR LOOP
   		 IF STU_REC.性别=1 THEN 	        
 	DBMS_OUTPUT.PUT_LINE(RPAD(STU_CURSOR%ROWCOUNT,8,' ')||RPAD(STU_REC编号,9,' ')||RPAD(STU_REC.姓名,9,' ')||'男||RPAD(STU_REC.总分,9,' ')||RPAD(STU_REC.录取志愿,9,' ')||RPAD
		(STU_REC.录取日期,9,' '));
ELSE
		DBMS_OUTPUT.PUT_LINE(RPAD(STU_CURSOR%ROWCOUNT,8,' ')||RPAD(STU_REC.编号,9,' ')||RPAD(STU_REC.姓名,9,' ')||'女  '||RPAD(STU_REC.总分,9,' ')||RPAD(STU_REC.录取志愿,9,' ')||RPAD
		(STU_REC.录取日期,9,' '));
   		 END IF;
 		 END LOOP;
		DBMS_OUTPUT.PUT_LINE('--------------------------------------------------------------------');
  		SELECT MAX(总分),MIN(总分) INTO V_MAX,V_MIN FROM STUDENT
WHERE 录取院校=P_YXBH;
 		 DBMS_OUTPUT.PUT_LINE(' 最高分'||V_MAX||' 最低分:'||V_MIN);
		END;

  说明:把院校编号作为条件,检索出被某个院校录取的考生,并按分数排序。其中,性别显示需要进行转换。过程中,使用了RPAD函数产生相等的列宽。在列表之后,通过统计查询,显示最高分和最低分。
10.院校招生情况统计表 COLLEGE_TOTAL
过程名和参数:
COLLEGE_TOTAL
功能:按照院校的平均录取分数排序所有院校,统计各院校的最高分数、最低分数,招生人数、录取人数、男生人数、女生人数等信息。
院校招生情况统计程序如下:
CREATE OR REPLACE PROCEDURE COLLEGE_TOTAL
		AS
V_YXBH NUMBER(4);
 		V_AVG NUMBER(4);
 		V_MAX NUMBER(4);
 		V_MIN NUMBER(4);
 		V_BOY NUMBER(3);
 		V_GIRL NUMBER(3);
 		V_ZSRS NUMBER(3);
		 V_LQRS NUMBER(3);
		 V_YXMC VARCHAR2(20);
 		CURSOR STU_CURSOR IS
 		SELECT 录取院校,AVG(总分),MAX(总分),MIN(总分) FROM STUDENT GROUP BY 录取院校 ORDER BY AVG(总分) DESC;
BEGIN
  		DBMS_OUTPUT.PUT_LINE('院校编号 院校名称   招生人数 录取人数 男生人数 女生人数 最高分数 最低分数 平均分数');
  		OPEN STU_CURSOR;
  		LOOP 
		   FETCH STU_CURSOR INTO 		V_YXBH,V_AVG,V_MAX,V_MIN;
  		 EXIT WHEN STU_CURSOR%NOTFOUND;
  		IF V_YXBH IS NOT NULL THEN
   		 SELECT 院校名称,招生人数,录取人数 INTO V_YXMC,V_ZSRS,V_LQRS 
FROM COLLEGE WHERE 院校编号=V_YXBH;
		    SELECT COUNT(*) INTO V_BOY FROM STUDENT WHERE 录取院校=V_YXBH AND 性别=1;
    		SELECT COUNT(*) INTO V_GIRL FROM STUDENT WHERE 录取院校=V_YXBH AND性别=2;
    		DBMS_OUTPUT.PUT_LINE(RPAD(V_YXBH,8,' ')||RPAD(V_YXMC,18,' ')||RPAD(V_ZSRS,9,' ')||RPAD(V_LQRS,9,' ')||RPAD(V_BOY,9,' ')||RPAD(V_GIRL,9,' ')||RPAD(V_MAX,9,' ')||RPAD(V_MIN,9,' ')||RPAD(V_AVG,9,' ')); 
END IF; 
  		END LOOP;
  		CLOSE STU_CURSOR;
		END;

说明:统计工作主要是通过一个按录取院校分组的查询游标来完成的。在分组查询中统计院校的平均分数、最高分和最低分,并按照平均分排序。其他信息在游标循环中根据院校编号通过查询语句得到。
触发器的设计
通过触发器可以为数据提供进一步的保护。下面设计两种常见类型的触发器。
1.分数修改触发器
如果要自动记录对数据库的数据进行的某些操作,可以通过创建触发器来实现。在考生数据库中,高考的分数字段的内容十分重要,是录取的最重要依据,应该正确设置对其进行操作的权限,并做好操作的记录。权限可以通过设定特定权限的账户进行控制,记录操作可以通过触发器来实现。
通过触发器来记录对考生表高考分数字段的插入、删除和修改操作,记录的内容可以包括:操作时间、操作人账户、执行的操作、考生编号、原分数和修改后的分数。以上内容记录到表OPERATION_LOG。
字段名称	类  型	宽度	约束条件	简 要 说 明
序号	number	10	主键	记录编号, 从1开始递增,取自序列
账户	varchar2	15	不允许为空	操作人账户
时间	date			操作时间,取自SYSDATE
操作	varchar2	10		操作种类
考生编号	number	5		考生编号
原分数	number	3		修改前的分数
新分数	number	3		修改后的分数

步骤1:创建如下的记录表OPERATION_LOGS:
CREATE TABLE OPERATION_LOG(
		序号 NUMBER(10) PRIMARY KEY,
		账户 VARCHAR2(15) NOT NULL,
		时间 DATE,
		操作 VARCHAR2(10),
		考生编号 NUMBER(5),
		原分数 NUMBER(3),
		新分数 NUMBER(3)
		);

步骤2:创建一个主键序列OPERATION_ID:
CREATE SEQUENCE OPERATION_ID  INCREMENT BY 1 
		START WITH 1 MAXVALUE 9999999 NOCYCLE NOCACHE;
		步骤3:创建和编译以下触发器:
		CREATE OR REPLACE TRIGGER OPERATION
		BEFORE --触发时间为操作前
		DELETE OR INSERT OR UPDATE OF 总分 -- 由三种事件触发
		ON STUDENT
FOR EACH ROW -- 行级触发器
		BEGIN
 		IF INSERTING THEN 
  		INSERT INTO OPERATION_LOG
		VALUES(OPERATION_ID.NEXTVAL,USER,SYSDATE,'插入',:NEW.编号,NULL,:NEW.总分);
		 ELSIF DELETING THEN
		  INSERT INTO OPERATION_LOG
VALUES(OPERATION_ID.NEXTVAL,USER,SYSDATE,'删除',:OLD.编号,:OLD.总分,NULL);
		ELSE
  		INSERT INTO OPERATION_LOG
  		VALUES(OPERATION_ID.NEXTVAL,USER,SYSDATE,'修改',:OLD.编号,:OLD.总分,:NEW.总分);
 		END IF;
		END;

说明:可参考触发器一章的相同类型触发器。
2.级联修改触发器
我们还可以创建级联修改触发器UPDATE_COLLEGE_NO,以实现如下的功能:当修改院校的编号时,自动修改学生表中与院校编号关联的字段内容。学生表共有3个字段与院校编号关联,即一志愿,二志愿和录取院校。
创建级联修改触发器:
CREATE OR REPLACE TRIGGER UPDATE_COLLEGE
 AFTER 
 UPDATE OF 院校编号 
 ON COLLEGE 
FOR EACH ROW  -- 行级触发器
BEGIN 
UPDATE STUDENT SET 一志愿=:NEW.院校编号  	WHERE 一志愿=:OLD.院校编号; 
  		 UPDATE STUDENT SET 二志愿=:NEW.院校编号  		WHERE 二志愿=:OLD.院校编号; 
   		UPDATE STUDENT SET 录取院校=:NEW.院校编号  WHERE 录取院校=:OLD.院校编号; 
		END;

说明:可参考触发器一章的相同类型触发器。
系统的测试和运行
运行准备
通过在SQL*Plus环境下使用SQL语句可以进行多种查询,来辅助录取过程获得信息。如果有必要的话,查询也可以设计成为存储过程,存储在数据库中,并可以进行调用。在这里,比较复杂不能通过SQL语句实现的查询或统计将通过存储过程或函数来实现。直接使用查询是进行测试的一种很好的方法,在这里也列出了一些可能用到的查询。
在投档前可以进行以下的查询。
1.按姓名进行模糊查询
查找姓王的考生:
SELECT 编号,姓名,性别,总分 FROM STUDENT WHERE 姓名 LIKE ‘王%’;

执行结果:
    
 编号 姓名            性       总分
		--------------- ------------------------ -- -----------------
     		10100 王聪            1         605

说明:姓王的考生只有王聪一个人。
2.按分数或分数段进行查询
查询分数在600~650分之间的考生:
SELECT 编号,姓名,性别,总分 FROM STUDENT WHERE 总分>600 AND 总分<650;

执行结果:
    
 编号 姓名            性       总分
		--------------- ------------------------- -- -----------------
     10053 黄宾            1         627
     10054 张晓羽          2         615
     10077 胡笛            2         610
     10081 李冠军          1         610
     10085 李丽            2         609
10089 曹万吉          2         617
    		 10093 邱雨林          2         608
    		 10099 孙庆            2         630
    		 10100 王聪            1         605
		已选择9行。 

说明:在600~650分之间有9名考生。
4.查询分数最高的考生报考的院校
查询分数最高的考生一志愿报考的院校:
SELECT 编号,姓名,性别,总分,院校名称 FROM STUDENT S,COLLEGE C WHERE  S.一志愿=C.院校编号 AND S.总分=(SELECT MAX(总分) FROM STUDENT);

执行结果:
     
编号 姓名            性       总分 院校名称
---------------- ------------------------ -- ----------------- ----------------------
     		10071 何健飞          1         689 清华大学 

说明:使用了统计查询和相等连接。分数最高的考生一志愿报考了清华大学。
5.查询招生人数最多的院校
查询招生人数最多的院校:
SELECT 院校名称,招生人数 FROM COLLEGE WHERE 招生人数=(SELECT MAX(招生人数) FROM COLLEGE); 

执行结果:
院校名称                         招生人数
		----------------------------------------------- --------------
		深圳职业技术学院        
                8
说明:使用了子查询。招生人数最多的院校是深圳职业技术学院。
6.查询考生分数
查询考生分数:
EXEC SHOW_SCORE(10005);

执行结果:
考生许小猛总分534
		PL/SQL 过程已成功完成。 

说明:调用存储过程并返回结果。编号为10005的考生许小猛,总分为534分。
7.检查OPERATION触发器的记录
检查OPERATION触发器的记录:
SELECT * FROM OPERATION_LOG;

执行结果:
...
    100 STUDENT     28-3月 -04 插入      10048          550
    101 STUDENT     28-3月 -04 插入      10049          630
    102 STUDENT      28-3月 -04 插入      10050         605
    103 STUDENT      28-3月 -04 修改       10045        555       553

说明:结果中显示了最近对STUDENT表的部分修改。通过最后一行可见,曾经将考生10045的总分由555改为553。
投档过程
1.初始化
初始化程序为:
SET SERVEROUTPUT ON SIZE 10000;
		EXEC CLEARSTATUS;

执行结果:
PL/SQL 过程已成功完成。

说明:在每次重新开始模拟投档时,都要先调用该过程进行初始化,清除原来的录取信息。2.一志愿自动投档
一志愿自动投档程序为:
EXEC AUTOPROC(1);

执行结果:
院校名称:清华大学一志愿投档开始
		-------------------------------------------------
编号:10021   姓名:何健飞  总分:689
编号:10020   姓名:张建锋  总分:688
编号:10012   姓名:张婷  总分:665
编号:10049   姓名:孙庆  总分:630
编号:10003   姓名:黄宾  总分:627
------------------------------------------------
院校名称:北京大学一志愿投档开始
-----------------------------------------------
编号:10004   姓名:张晓羽  总分:615
编号:10035   姓名:李丽  总分:609
编号:10036   姓名:吴子俊  总分:600
--------------------------------------------------

    说明:使用自动投档AUTOPROC进行一志愿投档,参数1代表一志愿投档。如果使用PROC1进行投档,则一次只能投档一个院校。通过执行结果可以看到,清华大学录取了5人,北京大学录取了3人。
3.查询考生录取状态
查询考生录取状态的程序为:
EXEC SHOW_RESULT(10005);

执行结果:
考生许小猛被暨南大学录取!
		PL/SQL 过程已成功完成。 

说明:查询编号为10005的考生录取状态,返回结果是许小猛被暨南大学录取。
4.二志愿自动投档
二志愿自动投档的程序为:
EXEC AUTOPROC(2);

执行结果:
院校名称:清华大学二志愿投档开始
		------------------------------------------------
		------------------------------------------------
		院校名称:北京大学二志愿投档开始
		------------------------------------------------
		编号:10027   姓名:胡笛  总分:610
-----------------------------------------------
院校名称:武汉大学二志愿投档开始
-----------------------------------------------
编号:10022   姓名:徐子钊  总分:600
编号:10013   姓名:李婷  总分:585
-----------------------------------------------

     说明:使用自动投档AUTOPROC进行二志愿投档,参数2代表二志愿投档。如果使用PROC2进行投档,则一次只能投档一个院校。结果显示,清华大学没有二志愿新录取的考生,北京大学有一名二志愿录取的考生......
5.查询录取情况视图
查询录取情况:
SELECT * FROM STATUS;

执行结果:
 
院校编号 院校名称                       状态     招生人数       缺额
		--------------- ---------------------------------------------- ------- -------------------- ---------------
	1001 清华大学                       完成            5          0
    1002 北京大学                    完成            4          0
    1003 武汉大学                    完成            6          0
    1004 华南科技大学            未完成          3          1
    1005 复旦大学                    未完成          4          2
    1006 中山大学                    未完成          5          3
1007 华南理工大学                 完成            4          0
      1008 暨南大学                       完成            3          0
      1009 深圳大学                       未完成         6          1
      1010 深圳职业技术学院        完成            8          0
	 已选择10行

说明:通过视图检查录取情况,可看到有6个学校已经完成录取,还有4所学校没有完成录取。华南科技大学缺额为1,复旦大学缺额为2......。没有完成的院校,可以设计调剂录取程序,来进一步投档。
统计报表
1.院校录取考生列表
显示深圳职业技术学院的录取考生列表,并按成绩排序:
EXEC STUDENT_LIST(1010);
执行结果:
深圳职业技术学院院校录取统计表
招生人数:8  录取人数:8   录取分数线:450
--------------------------------------------------------------------------------------------
序号    考生编号  姓名    性别   总分     录取志愿  录取日期
1       10001    陈文政   男     598      1        28-3月 -0
2       10048    陆文浩   男     550      2        28-3月 -0
3       10033    陈兵     男     498      1        28-3月 -0
4       10023    张庆旭   男     490      2        28-3月 -0
5       10016    周易     女     485      1        28-3月 -0
6       10010    袁慧瑶   女     477      2        28-3月 -0
7       10002    李敏     女     460      2        28-3月 -0
8       10008    尹文哲   男     455      2        28-3月 -0
--------------------------------------------------------------------------------------------
最高分:598 最低分:455

说明:从结果可以看出,深圳职业技术学院计划招生8人,已经录取8人。其中一志愿录取3人,二志愿录取5人。最高分数为589分,最低分数为455分,录取控制分数线为450分。
2.招生情况统计
显示按平均分降序排列的招生情况统计表:
EXEC COLLEGE_TOTAL;

执行结果:
院校编号 院校名称       招生人数 录取人数 男生人数 女生人数 最高分数 最低分数 平均分数
1001    清华大学   5     5    3    2   689   627   660
1002    北京大学    4    4    1    3    615  600    609
1005    复旦大学    4     2    2    0   610   600    605
1006    中山大学     5    2    0    2    608   587  598
1003    武汉大学    6     6      2     4     617  560      595
	1004    华南科技大学     3     2     1     1     595    588      592
	1007    华南理工大学     4     4     3      1    585    532      557
	1008    暨南大学     3     3      1     582    534    552
	1009    深圳大学     6     5      3    2     555    502  522
	1010    深圳职业技术学院 8    8     5    3     598    455    502
	PL/SQL 过程已成功完成。

说明:从结果可以看出,清华大学平均录取分数最高,为660分。该校计划招收5人,已经招满,其中男生3人,女生2人,最高分为689分,最低分为627分。
结果分析
系统招生录取过程中和结束后,应该对系统数据进行分析,检查是否存在投档错误,避免造成损失。如果发现问题,则要重新投档。
检查没有被录取的考生一志愿报考的院校:
SELECT 编号,姓名,总分,院校名称 FROM STUDENT S,COLLEGE C 
		WHERE S.一志愿=C.院校编号 AND S.录取志愿 IS NULL ORDER BY 总分 DESC;

执行结果:
    
编号 姓名                  总分 院校名称
--------------- ----------------------------- ----------- ------------------------------
     10045 张韦                   553 复旦大学
     10047 高飞云                 540 复旦大学
     10042 邓树林                 485 北京大学
     10030 国丹丹                 415 深圳大学
     10034 洪智力                 378 武汉大学

后5名考生因为分数不够(低于最低的录取分数线450分)不能被录取,前3名考生要对其进行检查(以第一个考生10045为例):
	SELECT * FROM STUDENT WHERE 编号=10045;

执行结果:
    
编号 姓名            性       总分       一志愿     二志愿 
		---------------- --------------------- ------ --------------------- -------------- --------------- 
    		 10045 张韦            2         553 1       1005       1007 

该生总分为553分,一志愿报1005,二志愿报1007。先检查一志愿的情况:
SELECT * FROM COLLEGE WHERE 院校编号=1005;

执行结果:
 
院校编号 院校名称         录取分数线   招生人数   录取人数
		--------------- ---------------------------------------------- ----------------- --------------- ----------------
	      1005 复旦大学                              580          4          2

复旦大学虽然没有招满,但因该考生的分数低于复旦大学的录取分数线,所以一志愿落选正常。继续检查二志愿情况:
SELECT * FROM COLLEGE WHERE 院校编号=1007;

执行结果:
 
院校编号 院校名称       录取分数线   招生人数   录取人数
--------------- ---------------------------------------------- ---------------- ---------------- ---------------
      	1007 华南理工大学          520          4          4

该考生达到了华南理工大学的录取分数线。该校招生4人,录取4人。继续检查该考生为什么没有被二志愿录取:
SELECT 编号,姓名,总分,录取志愿 FROM STUDENT WHERE 录取院校=1007 ORDER BY 总分 DESC;

执行结果:
    
 编号 姓名                  总分
	--------------- ------------------------------- ----------
     10017 罗惯通                 585 1
     10046 胡月                   557 1
     10006 杨煌                   555 2
     10041 林晨曦                 532 1

该校有3名考生被一志愿录取,二志愿录取1人。按照一志愿优先的原则,10045号考生只能参加二志愿投档。该校二志愿缺额1人,按分数从高到低排序,考生杨煌的分数555高于考生张韦的分数553,故杨煌优先录取,达到录取人数4人,录取结束。
通过以上分析可知,张韦没有被录取属于正常情况。
对其他考生的情况分析可以模仿以上步骤进行。
系统改进
至此完成了高校招生模拟的全部工作。该系统在以下方面还有待于改进:
(1) 可按照模块功能以包的形式对模块进行分类,比如可以分为投档包、查询包和公用包。
(2) 可以设立多个应用账户,通过授予不同的系统权限对象及包的访问权限,来限定对数据的访问和操作。
(3) 进一步完成调剂投档的程序。
以上工作,有兴趣的读者可以进一步完善。
练习
设计开发“图书管理系统”,完成图书的入库、查询、出借、归还和信息统计工作。系统主要的表应该包括图书表、出版社表、图书出借表和读者表(参照第4章内容)。
系统的主要功能包括:
(1) 插入修改图书表、出版社表和读者表。
(2) 按图书名称、出版社、出版时间和作者检索图书。
(3) 对图书进行模糊检索。
(4) 出借和归还图书。
(5) 查询过期未归还的图书。
(6) 查询在借图书的有关信息。
(7) 热门图书统计(按出借次数统计)。
(8) 按日期查询新进图书。

黑色头发:http://heisetoufa.iteye.com/

你可能感兴趣的:(设计模式,数据结构,oracle,sql,出版)