舰队管理系统分析与设计-舰队管理系统分析与设计(Oracle),功能需求,数据字典,软件工程

大型数据库技术项目

舰队管理系统分析与设计

舰队管理系统

1、项目背景介绍

中美海军实力对比分析:

中国海军虽然有了很大的进步,但是我们和世界先进的海军的实力有着很大差距,通过对比中美海军主战舰的数量和性能,中国海军要想拥有能与美国匹敌的能力和远距离投送兵力,至少需要十年的时间,或是更长的时间。

航空母舰

中国:无

美国:11艘核动力航母

两栖攻击舰

中国:无

美国:11艘可携带短距离起飞/垂直降落战斗机的两栖攻击舰

导弹巡洋舰

中国:无

美国:22艘导弹巡洋舰

驱逐舰:

中国:27艘吨位不同、性能参差不齐的驱逐舰

美国:60艘“阿利伯克”级驱逐舰

护卫舰:

中国:48艘护卫舰和护卫艇

美国:30艘护卫舰

潜艇

中国:3艘弹道核潜艇、6艘攻击型核潜艇、55艘柴电潜艇

美国:14艘弹道导弹核潜艇、57艘攻击型核潜艇、并以全部淘汰柴电潜艇

2、功能需求

美国海军的装备性能大幅领先于中国海军,近年来,美国又出台了新的军事战略政策,重返亚太,在这个关键时刻,依据我们现有的战舰,如何管理,分配人员,安装武器等是个首要问题。

在该系统中有四个模块:

1. 舰队信息管理

2. 舰艇信息管理

3. 兵官信息管理

4. 武器信息管理

同时在该四个系统中要分别进行插入,查询,修改等修改。

2.1 舰队管理系统完成主要功能

该系统的功能模块如下:

2.2系统功能的结构设计

系统功能的结构设计:

1. 舰队信息的基本输入,包括舰队名称、基地地点、舰艇数量

2. 舰队基本信息查询,修改与删除,包括舰队的名称、基地地点、舰艇数量

3. 舰艇信息的基本输入,包括舰艇编号、舰艇名称、武器名称、士兵数量、武器数量、舰艇功能

4. 舰艇基本信息查询、修改与删除,包括舰艇编号、舰艇名称、武器名称、士兵数量、武器数量、舰艇功能

5. 兵官信息的基本输入,包括官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

6. 兵官基本信息查询、修改、删除,包括官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

7. 武器基本信息的输入,包括武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

8. 武器信息的查询、修改、删除,包括武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

3、数据需求

根据调查分析,得出:

(1) 一个舰队有多艘舰艇;

(2) 一个舰队只能有一个舰队名称,一个舰队名称只能属于一个舰队;

(3) 一艘舰艇属于一支舰队;

(4) 一艘舰艇只能有一个舰艇编号,一个舰艇编号只能属于一艘舰艇;

(5) 一艘舰艇可以安装多种武器;

(6) 一种武器可安装于多艘舰艇上;

(7) 一种武器只能有一个武器名称,一个武器名称只能属于一种武器;

(8) 一艘舰艇有多个官兵;

(9) 一个官兵只属于一艘舰艇;

(10) 一个官兵只有一个证号,一个证号只属于一个官兵。

通过与用户的沟通,获得系统的数据存储需求如下:

舰队方面

舰队:舰队名称、基地地点、舰艇数量

舰艇:舰艇编号、舰艇名称、舰队名称、士兵数量、武器数量、舰艇功能

舰艇方面

舰艇:舰艇编号、舰艇名称、武器名称、士兵数量、武器数量、舰艇功能

武器:武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

官兵:官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

3.1数据流图

3.2数据字典

3.2.1数据项:

数据项:舰队名称

含义说明:唯一标识每个舰队

别名:舰队名

类型:字符型

长度:12

数据项:基地地点

含义说明:标识基地地点

别名:基地名

类型:字符型

长度:12

数据项:舰艇数量

含义说明:舰艇的数量

别名:舰艇数

类型:数值型

长度:小数位数 0

取值范围:1~100

数据项:舰艇编号

含义说明:唯一标识每艘舰艇

别名:舰艇号

类型:字符型

长度:12

数据项:舰艇名称

含义说明:每艘舰艇的名称

别名:舰艇名

类型:字符型

长度:12

数据项:武器型号

含义说明:唯一标识每种武器的名称

别名:武器名

类型:字符型

长度:12

数据项:武器生产时间

含义说明:每种武器的出厂日期

别名:武器出产日

类型:日期型

数据项:官兵证号

含义说明:唯一标识每位官兵

别名:官兵号

类型:字符型

3.2.2数据结构:

数据结构:舰队

含义说明:舰队管理系统的主体数据结构,定义一个舰队有关信息

组成:舰队名称、基地地点、舰艇数量

数据结构:舰艇

含义说明:舰队管理系统的主体数据结构,定义一个舰艇的有关信息

组成:舰艇编号、舰艇名称、舰队名称、士兵数量、武器数量、舰艇功能

数据结构:武器

含义说明:舰队管理系统的主体数据结构,定义一种武器的有关信息

组成:武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

数据结构:官兵

含义说明:舰队管理系统的主体数据结构,定义一个官兵的有关信息

组成:官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

3.2.3数据流:

数据流:安装

说明:舰艇上安装武器

数据流来源:武器

数据流去向:舰艇

组成:武器名称,舰艇编号,安装时间

平均流量:……

高峰期流量:……

数据流:拥有

说明:舰队拥有舰艇的数量

数据流来源:舰艇

数据流去向:舰队

组成:舰艇数量

平均流量:……

高峰期流量:……

数据流:属于

说明:舰艇上的官兵

数据流来源:官兵

数据流去向:舰艇

平均流量:……

高峰期流量:……

3.2.4数据存储:

数据存储:武器信息表

说明:记录武器的基本信息

流入数据流:……

流出数据流:舰艇

组成:武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

数据量:……

存取方式:随机存取

数据存储:舰艇信息表

说明:记录舰艇的基本信息

流入数据流:……

流出数据流:舰队

组成:舰艇编号、舰艇名称、舰队名称、士兵数量、武器数量、舰艇功能

数据量:……

存取方式:随机存储

数据存储:官兵信息表

说明:记录官兵的基本信息

流入数据流:……

流出数据流:舰艇

组成:官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

数据量:……

存取方式:随机存取

数据存储:舰队信息表

说明:记录舰队基本信息

流入数据:舰艇

流出数据:……

组成:舰队名称、基地地点、舰艇数量

数据量:……

存取方式:随机存储

3.2.5处理过程:

处理过过程:武器对舰艇的安装

说明:为每艘舰艇安装武器

输入:舰艇编号、武器名称

输出:武器安装

处理:一种武器可安装于多艘舰艇上,一种武器只能有一个武器名称,一个武器名称只能属于一种武器。

处理过程:舰艇对官兵的分配

说明:为每艘舰艇分配官兵

输入:官兵证号、姓名、舰艇编号

输出:舰艇名

处理:一艘舰艇有多个官兵,一个官兵只能属于一艘舰艇。

处理过程:舰队对舰艇的分配

说明:为每支舰队分配舰艇

输入:舰艇编号、舰队名称

输出:舰队名称

处理:一支舰队有多艘舰艇,一艘舰艇只能属于一支舰队

4、概念结构设计阶段

将需求分析得到的用户需求抽象为抽象为反应用户观点的信息结构(即概念模型)的过程就是概念结构设计,它是整个数据库设计的关键。概念设计独立于计算机硬件结构,并且支持数据库的DBMS。

概念结构设计阶段主要是将需求分析阶段得到的用户需求抽象为信息(概念模型)的过程,它是整个数据库设计的关键。描述概念模型的方法有E-R图和UML图两种,这里采用比较常见的E-R模型表示方法。

具体设计步骤如下:

(1) 选择中层数据流为切入点,通常选择系统中的子系统

(2) 设计分E-R图,及各子模块的子系统

(3) 生成初步E-R图,通过合并的方法,统一各实体、属性、联系

(4) 生成全局E-R图,通过消除冲突等方面

Power Designer的使用

4.1 CDM

CDM:

4.2舰队实体

4.3武器实体

4.4兵官实体

4.5舰艇实体

4.6 整体E-R图

舰队:舰队名称、基地地点、舰艇数量

舰艇:舰艇编号、舰艇名称、武器名称、士兵数量、武器数量、舰艇功能

武器:武器型号、武器名称、武器生产时间、武器功能、武器名称、武器价格

官兵:官兵证号、舰艇编号、官兵姓名、工资、家乡地、年龄、性别

5、逻辑结构设计

概念结构是独立于任何一种数据模型的信息结构。逻辑结构设计的任务就是把概念结构的设计好的基本的E-R图转换为选用的DBMS产品所支持的逻辑结构。

5.1逻辑结构的设计步骤

概念模型映射为逻辑结构模型分为三步:

(1) 将概念模型转化为一般的关系、网状、层次模型。在这一步,映射不考虑特殊情况。

(2) 使用所选的DBMS来创建数据库的概念模式和外模式。不同的DBMS使用各自特定的特性和约束来实现数据模型。因此,有可能需对第一步所得的模型进行修改。该阶段得到的结果是用所选的DBMS语言编写的DDL语句。这些语句包括数据库系统的概念模式和外模式。

1)一个舰队有多艘舰艇;

2)一个舰队只能有一个舰队名称,一个舰队名称只能属于一个舰队;

3)一艘舰艇属于一支舰队;

4)一艘舰艇只能有一个舰艇编号,一个舰艇编号只能属于一艘舰艇;

5)一艘舰艇可以安装多种武器;

6)一种武器可安装于多艘舰艇上;

7)一种武器只能有一个武器名称,一个武器名称只能属于一种武器;

8)一艘舰艇有多个官兵;

9)一个官兵只属于一艘舰艇;

10)一个官兵只有一个证号,一个证号只属于一个官兵。

转换应遵循的原则:实体的属性就是关系的属性,实体的码就是关系的码。

5.2关系模式

分析得到的关系模式:

舰队(舰队名称,基地地点,舰艇数量)

舰艇(舰艇编号,舰队名称,舰艇名称,士兵数量,武器数量,舰艇功能)

官兵(官兵证号,舰艇编号,姓名,性别,年龄,家乡地,工资)

武器(武器型号,武器名称,武器生产时间,武器功能,价格)

安装(舰艇编号,武器名称,安装日期)

注:加下划线的是主键,加波浪线的是外键。

Fleet(Fleet_name,base, Warship_count)

Warship_ship(Warship_num,Fleet_name,Warship_name,Soldiers_count,Weapon_count,Warship_function)

Soldiers(Soldiers_num,Warship_num,Soldiers_name,Soldiers_sex,Soldiers_age, Soldiers_home, Soldiers_sal)

Weapon(Weapon_num,Weapon_name,Weapon_date,Weapon_function,Weapon_price)

Install(Warship_num,Weapon_name, Install_date)

5.3LDM:

(3)对数据模型进行优化

在舰队,舰艇,官兵,武器,安装,关系模式中,每个属性都已达到原子属性,则已达到1NF,同理在舰队,舰艇,官兵,武器,关系模式中因为候选键都完全函数决定非主属性,所以都达到了2NF;又因为在各个关系模式中候选键不传递决定于非主属性。则达到了3NF;

5.4数据库模式的定义

舰队基本信息表


列名


数据类型


可否为空


说明


FLEET_NAME


CHAR(30)


NOT NULL


舰队名


WARSHIP_COUNT


NUMBER(38)


舰艇数量


BASE


CHAR(40)


NOY NULL


基地

舰艇基本信息表


列名


数据类型


可否为空


说明


WARSHIP_NUM


CHAR(30)


NOT NULL


舰艇编号


FLEET_NAME


CHAR(30)


舰队名


WARSHIP_NAME


CHAR(30)


NOT NULL


舰艇名


SOLDIERS_COUNT


NUMBER(38)


士兵数量


WEAPON_COUNT


NUMBER(38)


武器数量


WARSHIP_FUNCTION


CHAR(50)


NOT NULL


舰艇功能

士兵基本信息表


列名


数据类型


可否为空


说明


SOLDIER_NUM


CHAR(30)


NOT NULL


士兵名


WARSHIP_NUM


CHAR(30)


舰艇编号


SOLDIERS_NAME


CHAR(20)


NOT NULL


士兵名


SOLDIERS_SEX


CHAR(2)


士兵性别


SOLDIERS_AGE


NUMBER(38)


士兵年龄


SOLDIERS_HOME


CHAR(50)


家乡地


SOLDIERS_SAL


NUMBER(38)


工资

武器基本信息表


列名


数据类型


可否为空


说明


WEAPON_NUM


CHAR(30)


NOT NULL


武器编号


WEAPON_NAME


CHAR(50)


NOT NULL


武器名


WEAPON_DATE


DATE


生存日期


WEAPON_FUNCTION


CHAR(50)


NOT NULL


武器功能


WEAPON_PRICE


NUMBER(38)


价格

安装信息表


列名


数据类型


可否为空


说明


WAESHIP_NUM


CHAR(30)


NOT NULL


舰艇编号


WEAPON_NUM


CHAR(30)


NOT NULL


武器编号


INSTALL_DATE


DATE


NOT NULL


安装日期

六、数据库物理设计

数据库在物理设备上的存储结构与存取方法称为数据库的物理结构,它依赖于给定的计算机系统。

6.1数据库物理设计的步骤

(1) 确定数据库的物理结构,在关系数据库中的主要指存储方法和存储结构。

(2) 对物理就够进行评价,评价的重点是时间效率。

如果评价的结果满足原设计的要求,则可进入物理实施阶段,否则需重新设计或修改物理结构,有时甚至应返回逻辑设计阶段,修改数据模型。

关系数据库物理设计的内容:为关系模型选择存取方法(建立存取路径);设计关系,索引等数据库文件的物理存储结构。

6.2关系模式存取方式:

DBMS常用的存取方式有以下两种:

(1)索引存取

(2)聚簇存取

(3)HASH存取

现在主要就索引存取:

(1)在舰艇表的warship_name列上创建一个索引,这样就可以使在以舰艇名为条件查找其他信息时,提高查找的效率。

SQL> create index warship_name_index on warship_ship(warship_name);

索引已创建。

查找当舰艇名为两栖攻击舰时的舰艇编号和舰艇功能,就可以很快速的得到以下信息:

(2)创建复合索引:

下面这个例子就是通过查找士兵工资大于等于3000,且年龄小于30的士兵信息。首先要创建一个复合索引,在产品表的价格和产品总数两个列上创建复合索引。

6.3确定数据库的存储结构

主要是指确定数据的存放位置和存储结构,包括关系,索引,聚簇,日志,备份等的存储安排和存储结构:确定系统的配置等。确定数据的存放位置和存储结构要综合考虑存取时间,空间,维护代价三方面,这三方面常常是相互矛盾的,如消除一切冗余数据虽能够节约存储时间和减少维护代价,但往往会导致检索代价的增加,因此必须进行权衡,选择一个折中的方案。

(1) 确定数据的存放位置:根据应用情况将数据的异变部分与稳定部分、经常存取部分与存取频率较低部分分开存放,以提高系统性能。例如,数据库数据备份、日志文件备等由于只在故障恢复时才使用,而且数据量很大,可以考虑存放在磁带上:如果计算机有多个磁盘,可以考虑将表和索引部分分别存放在不同的磁盘上,查询时由于两个磁盘在工作,因而可以保证物理读写速度比较快:可以将较大的表分别放在两个磁盘上,以加快存取速度,在多用户环境下特别有效:可以将日志文件与数据库对象(表和索引)放在不同的磁盘上以改进系统性能。

(2) 确定系统配置:DBMS产品提供的存储分配参数有同时使用数据库的用户数和对象数、使用的缓冲区长度和个数、时间片大小、数据库大小、装填因子、锁的数目等。系统都为这些变量赋了合理的缺省值,但这些值不一定适应各种应用环境,物理设计需要根据应用环境确定这些参数值,以使系统性能最优。物理设计时对系统配置变量的调整只是初步的,在系统运行时还要根据系统实际运行情况作进一步的调整,以此来改进系统的性能。

6.4 PDM

7、数据库的实施及维护

完成了逻辑设计和物理设计后,就可以着手实现数据库系统了。通常,这部分工作有DBA负责,数据库设计人员协助共同完成。用DDL语言对概念模式和外模式,然后向数据库中装载数据。如果要从以前的系统中转换数据,可以使用转换程序重新对数据进行格式化,以便装载到新的数据库中。实施完成,系统进入正常的运行维护直至死亡。

7.1数据库的实施

1. 数据的载入

2. 应用程序的编制与调试

7.2数据库试运行

(1) 试运行的任务

(2) 数据的分期入库

(3) 数据库的转储和恢复

7.3数据的运行和维护

(1) 数据库的转储和恢复

(2) 数据库的安全性、完整性控制

(3) 数据库的监督、分析和改进

(4) 数据库的重组织和重构造

7.4创建表空间:

SQL>  create tablespace wqh_tablespace

2   datafile ‘f:\wqh_tablespace01.dbf‘ size 100m

3  extent management local

4  segment space management auto;

表空间已创建。

为了防止在使用过程中表空间不足,则可以为它添加新的数据文件以增大表空间(因为数据文件的大小决定了创建的表空间的大小,表空间的大小等于不同磁盘上所有数据文件的大小之和):

SQL> alter tablespace wqh_tablespace

2  add datafile ‘d:\wqh_tablespace02.dbf‘ size 100m;

表空间已更改。

查看该表空间数据文件的路径:

7.5创建用户

SQL> create user wqh

2  identified by 1215115130

3  default tablespace wqh_tablespace

4  temporary tablespace temp;

用户已创建。

7.6分配权限:

SQL> grant create session,resource to wqh;

授权成功。

再给用户wqh授予创建视图的权限和为用户wqh授予创建同义词的权限:

SQL> conn / as sysdba;

已连接。

SQL> grant create view to wqh;

授权成功。

SQL> grant create synonym to wqh;

授权成功。

7.7创建用户配置文件:

创建一个名为res_profile的概要文件,要求每个用户最多可以创建5个并发会话;每个会话持续时间最长为60分钟;如果会话在连续30分钟内空闲,则结束会话;每个会话的私有SQL区为100 KB;每个SQL语句占用CPU时间总量不超过100秒。

SQL> create profile res_profile limit

2  sessions_per_user 5 connect_time 60

3  idle_time 30 private_sga 100k

4   cpu_per_call 100;

配置文件已创建

修改用户为用户指定概要文件:

SQL> alter user wqh profile res_profile;

用户已更改。

7.8从power designer的PDM阶段所得到的建表语句

如下:

舰队表:

create table Fleet

(

Fleet_name           char(30)                       not null,

Warship_count        integer                        null,

base                 char(40)                       not null,

constraint PK_FLEET primary key (Fleet_name)

);

舰艇表:

create table Warship_ship

(

Warship_num          char(30)                       not null,

Fleet_name           char(30)                       null,

Warship_name         char(30)                       not null,

Soldiers_count       numeric                        null,

Weapon_count         numeric                        null,

Warship_function     char(50)                       not null,

constraint PK_WARSHIP_SHIP primary key (Warship_num)

);

为舰艇表添加Fleet_name外键

alter table Warship_ship

add constraint FK_WARSHIP__HAVE_FLEET foreign key (Fleet_name)

references Fleet (Fleet_name);

士兵表:

create table Soldiers

(

Soldier_num          char(30)                       not null,

Warship_num          char(30)                       null,

Soldiers_name        char(20)                       not null,

Soldiers_sex         char(2)                        null,

Soldiers_age         integer                        null,

Soldiers_home        char(50)                       null,

Soldiers_sal         numeric                        null,

constraint PK_SOLDIERS primary key (Soldier_num)

);

为士兵表添加Warship_num外键

alter table Soldiers

add constraint FK_SOLDIERS_BELONG_WARSHIP_ foreign key (Warship_num)

references Warship_ship (Warship_num);

武器表:

create table Weapon

(

Weapon_num           char(30)                       not null,

Weapon_name         char(50)                       not null,

Weapon_date          date                           null,

Weapon_function      char(50)                       not null,

Weapon_price         numeric                        null,

constraint PK_WEAPON primary key (Weapon_num)

);

安装表:

create table Install

(

Warship_num          char(30)                       not null,

Weapon_num           char(30)                       not null,

Install_date         date                           not null,

constraint PK_INSTALL primary key (Warship_num, Weapon_num)

);

为安装表添加Weapon_num外键

alter table Install

add constraint FK_INSTALL_IW_WEAPON foreign key (Weapon_num)

references Weapon (Weapon_num);

为安装表添加Warship_num外键

alter table Install

add constraint FK_INSTALL_WI_WARSHIP_ foreign key (Warship_num)

references Warship_ship (Warship_num);

7.9在oracle数据库的wqh用户进行建表

如下:

创建舰队表

创建舰艇表:

为舰艇表添加Fleet_name外键:

创建士兵表:

为士兵表添加Warship_num外键:

创建武器表:

创建安装表:

为安装表添加Weapon_num外键:

为安装表添加Warship_num外键:

7.10视图的创建

1. 创建一个视图,规定该视图中有士兵表中的士兵编号,舰艇编号,官兵姓名

2. 创建一个包含舰艇编号,舰队名称,士兵数量,武器数量的视图。

3. 可以创建一个连接视图,用来查询同一个舰队所包含的舰艇信息,以及员工名字的视图:

create view fleet_warship_view(舰艇编号,舰队名字,舰艇名字,基地地点)

as

select warship_ship.warship_num, warship_ship.fleet_name, warship_ship.warship_name,fleet.base

From warship_ship,fleet

Where warship_ship.fleet_name=fleet.fleet_name;

查询结果如下:

4.创建一个视图,里面有信息:员工编号,员工名,订单编号,订单日期,客户编号,客户名

create view warship_install_weapon_view(舰艇编号,舰队名称,武器数量,安装日期,武器型号,武器价格)

as

select warship_ship.warship_num, warship_ship.fleet_name, warship_ship.weapon_count,install.install_date,weapon.weapon_num,weapon.weapon_price

from warship_ship, install, weapon

where warship_ship.warship_num=install. warship_num and install.weapon_num=weapon.weapon_num;

视图已创建。

7.11创建同义词

同义词是数据库中表、索引、视图或其他模式对象的一个别名。若是为士兵表创建一个同义词,如果想为其中的某个士兵涨工资,则就可以通过该表的同义词来实现对士兵表的操作,如下:

这时可以通过更新同义词来实现对订单表的更新,如下:

update lists_synonym

set clerkno=’0001’

where lno=’A_000010’;

在没有更新之前的数据是:

现在更新之后,结果如下:

7.12存储过程的创建

1.创建一个存储过程,以舰艇号为参数,查询该舰艇中所有士兵的平均工资,并输出该舰艇中比平均工资高的士兵编号、士兵名。

CREATE OR REPLACE PROCEDURE soldiers_produce(

p_warship_num soldiers.warship_num%TYPE)

--以舰艇号为参数

AS

v_sal soldiers.soldiers_sal%TYPE;

BEGIN

SELECT avg(soldiers_sal) INTO v_sal FROM soldiers

WHERE warship_num=p_warship_num;

--查询该舰艇中所有士兵的平均工资

DBMS_OUTPUT.PUT_LINE(p_warship_num||‘ ‘||‘average salary is:‘

||v_sal);

FOR v_soldiers IN (SELECT * FROM soldiers

WHERE warship_num=p_warship_num AND soldiers_sal>v_sal) LOOP

DBMS_OUTPUT.PUT_LINE(v_soldiers.soldier_num||‘ ‘||v_soldiers.soldiers_name);

--输出该舰艇中比平均工资高的士兵编号、士兵名

END LOOP;

EXCEPTION

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE(‘The warship doesn’’t exists!‘);

--当舰艇不存在时,输出语句The warship doesn’’t exists!

END soldiers_produce;

执行的结果如下:

3. 创建一个存储过程,以舰艇号为参数,返回该舰艇所含有的士兵人数和士兵的平均工资。

CREATE OR REPLACE PROCEDURE warship_soldiers_pro(

p_warship_num soldiers.warship_num%TYPE,

p_avgsal OUT soldiers.soldiers_sal%TYPE,

p_count  OUT soldiers.soldiers_sal%TYPE)

--以舰艇号为参数

AS

BEGIN

SELECT avg(soldiers_sal),count(*) INTO p_avgsal,p_count

--返回该舰艇士兵的平均工资和所含有的士兵人数

FROM soldiers

WHERE warship_num=p_warship_num;

EXCEPTION

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE(‘The warship doesn’’t exists!‘);

END warship_soldiers_pro;

3.输出某个舰艇士兵的姓名及工资档次,3000以上高,2500-3000中等,2000-2500较低,2000以下低。

create or replace procedure soldiers_name_level

(dnum in soldiers.soldier_num%type,

name out soldiers.soldiers_name%type,level out varchar2)

as

salary soldiers.soldiers_sal%type;

begin

select soldiers_sal,soldiers_name

into salary,name from soldiers

where dnum=soldier_num;

--查找士兵的工资和姓名

case

when salary >3000 then level:=‘高‘;

--当士兵的工资大于3000时输出:高

when salary between 2500 and 3000 then level:=‘中等‘;

--当士兵的工资大于2500小于3000时输出:中等

when salary between 2000 and 2500 then level:=‘较低‘;

--当士兵的工资大于2000小于2500时输出:较低

else  level:=‘低‘;

--当士兵的工资低于2000时输出:较低

end case;

end;

/

4. 获取某舰艇所包含士兵的工资总和及该舰艇的名称。

create or replace procedure warship_pro

(e_warship_num soldiers.warship_num%type)

as

cursor soldiers_cur is--游标名为soldiers_cur

select warship_num,sum(soldiers_sal) as e_sal

from soldiers

where warship_num=e_warship_num

group by warship_num;

--以舰艇编号分组

begin

for soldiers_record1 in soldiers_cur loop

dbms_output.put_line(soldiers_record1.warship_num||‘ ‘

||soldiers_record1.e_sal);

--输出该舰艇所包含士兵的工资总和及该舰艇的名称

end loop;

end;

/

过程已创建。

7.13函数的创建

1. 创建一个以舰艇号为参数,返回该舰艇所包含的士兵中最高工资的函数。

CREATE OR REPLACE FUNCTION return_maxsal

(p_warship_num soldiers.warship_num%TYPE)

--以舰艇号为参数

RETURN soldiers.soldiers_sal%TYPE

--以士兵的工资作为返回值

AS

v_maxsal soldiers.soldiers_sal%TYPE;

BEGIN

SELECT max(soldiers_sal) INTO v_maxsal FROM soldiers

WHERE warship_num=p_warship_num;

RETURN v_maxsal;--返回该舰艇所包含的士兵中最高工资

EXCEPTION

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE(‘The warship_num is invalid!‘);

END return_maxsal;

注释:在当舰艇号为056时所包含的员工中工资最高位3800

注释:在当舰艇号为0981时所包含的员工中工资最高位2800

2. 获取某士兵的工资:  

create or replace function soldiers_sal

(soldier1_num in soldiers.soldier_num%type)

--以士兵的编号为参数

return soldiers.soldiers_sal%type

--返回士兵的工资

as

salary soldiers.soldiers_sal%type;

begin

select soldiers_sal into salary

from soldiers

where soldier1_num=soldier_num;

return salary;

--返回士兵的工资

end;

/

函数已创建。

3.计算指定舰艇中员工的工资总和,并统计该舰艇中的士兵数量。

create or replace function salnum_soldiernum

(dnum in soldiers.soldier_num%type,total out soldiers.soldiers_sal%type)

return number

--返回士兵的数量

as

e_count number;

begin

select sum(soldiers_sal),count(soldier_num)

--计算指定舰艇中员工的工资总和,统计该舰艇中的士兵数量

into total,e_count

from soldiers

where warship_num=dnum;

return e_count;

end;

/

函数已创建。

declare

total soldiers.soldiers_sal%type;

begin

dbms_output.put_line(‘snum:‘||salnum_soldiernum(‘8‘,total)

||‘‘||‘total:‘||total);

end;

/

4. 如果需要函数返回多个值,可以使用OUT或IN OUT模式参数。

创建一个函数,以舰艇号为参数,返回舰艇名、舰艇所包含的士兵人数及该舰艇的平均工资。

CREATE OR REPLACE function return_warship_soldiers(

p_warship_num warship_ship.warship_num%TYPE,

p_num OUT NUMBER,

p_avg OUT NUMBER)  --以舰艇号为参数

RETURN warship_ship.warship_name%TYPE  --返回舰艇名

AS

v_warship_name warship_ship.warship_name%TYPE;

BEGIN

SELECT warship_name INTO v_warship_name

FROM warship_ship

WHERE warship_num=p_warship_num;

SELECT count(*),avg(soldiers_sal)

INTO p_num,p_avg

FROM soldiers

WHERE warship_num=p_warship_num;

RETURN v_warship_name;   --返回舰艇名

END return_warship_soldiers;

5. 输出某个士兵的姓名及工资档次,3000以上高,2500-3000中等,

2000-2500较低,2000以下低。

create or replace function soldiers_sal_level

(dnum in soldiers.soldier_num%type,

name out soldiers.soldiers_name%type)

--以士兵的士兵编号为参数

return varchar2

as

salary soldiers.soldiers_sal%type;

level varchar2(15);

begin

select soldiers_sal,soldiers_name into salary,name

from soldiers

where dnum=soldier_num;

case

when salary >3000 then level:=‘高‘;

--当士兵的工资大于3000时输出:高

when salary between 2500 and 3000 then level:=‘中等‘;

--当士兵的工资大于2500小于3000时输出:中等

when salary between 2000 and 2500 then level:=‘较低‘;

--当士兵的工资大于2000小于2500时输出:较低

else  level:=‘低‘;

--当士兵的工资低于2000时输出:较低

end case;

return level;

end;

/

函数已创建。

7.14局部子程序:

在一个块内部定义一个函数和一个过程。

函数以舰艇号为参数返回该舰艇中士兵的平均工资;过程以舰艇号为参数,

输出该舰艇中士兵工资低于该舰艇平均工资的士兵的士兵号、士兵名。

DECLARE

v_warship_num soldiers.warship_num%TYPE;

v_avgsal soldiers.soldiers_sal%TYPE;

FUNCTION return_avgsal(p_warship_num soldiers.warship_num%TYPE)

--以舰艇编号为参数

RETURN soldiers.soldiers_sal%TYPE

--返回该舰艇中士兵的平均工资

AS

v_sal soldiers.soldiers_sal%TYPE;

BEGIN

SELECT avg(soldiers_sal) INTO v_sal FROM soldiers

WHERE  warship_num=p_warship_num;

RETURN v_sal;

END return_avgsal;

PROCEDURE show_soldiers(p_warship_num soldiers.warship_num%TYPE)

--以舰艇号为参数

AS

CURSOR c_soldiers IS

SELECT * FROM soldiers WHERE warship_num=p_warship_num;

BEGIN

FOR v_soldiers IN c_soldiers LOOP

IF v_soldiers.soldiers_sal<return_avgsal(v_soldiers.warship_num)

THEN

DBMS_OUTPUT.PUT_LINE(v_soldiers.soldier_num||‘ ‘||

v_soldiers.soldiers_name);

--输出该舰艇中士兵工资低于该舰艇平均工资的士兵的士兵号、士兵名

END IF;

END LOOP;

END show_soldiers;

BEGIN

v_warship_num:=&x;

v_avgsal:=return_avgsal(v_warship_num);

show_soldiers(v_warship_num);

END;

7.15触发器的创建

1. 为soldiers士兵表创建一个触发器,当执行插入操作时,统计操作后士兵人数;当执行更新工资操作时,统计更新后士兵的平均工资;当执行删除操作时,统计删除后各个舰艇所包含士兵的人数。

CREATE OR REPLACE TRIGGER trg_soldiers_dml

AFTER INSERT OR UPDATE OR DELETE ON soldiers

DECLARE

v_count NUMBER;

v_sal   NUMBER(6,2);

BEGIN

--当执行插入操作时,统计操作后士兵人数

IF INSERTING THEN

SELECT count(*) INTO v_count FROM soldiers;

DBMS_OUTPUT.PUT_LINE(v_count);

--当执行更新工资操作时,统计更新后士兵的平均工资;

ELSIF UPDATING THEN

SELECT avg(soldiers_sal) INTO v_sal FROM soldiers;

DBMS_OUTPUT.PUT_LINE(v_sal);

--当执行删除操作时,统计删除后各个舰艇所包含士兵的人数。

ELSE

FOR v_warship_ship IN

(SELECT warship_num,count(*) num FROM soldiers

GROUP BY warship_num) LOOP

DBMS_OUTPUT.PUT_LINE(v_warship_ship.warship_num

||‘ ‘||v_warship_ship.num);

END LOOP;

END IF;

END trg_soldiers_dml;

2. 修改士兵的工资时,保证修改后的士兵工资高于修改前的士兵工资。

CREATE OR REPLACE TRIGGER trg_soldiers_update_row

BEFORE UPDATE OF soldiers_sal ON soldiers

--指定触发时机为更新士兵soldiers表的列soldiers_sal操作前触发

FOR EACH ROW  --说明创建的是行级触发器

WHEN(new.soldiers_sal<=old.soldiers_sal)

--当更新后的数小于更新前的数,则会输出-20001,‘The soldiers_sal is lower!

BEGIN

RAISE_APPLICATION_ERROR(-20001,‘The lnumber is lower!‘);

END trg_soldiers_update_row;

3.修改warship_ship表的warship_num列时,同时把soldiers表中相应的warship_num也作相应的修改;

set serveroutput on

CREATE OR REPLACE TRIGGER tr_warship_soldiers

AFTER update OF warship_num ON warship_ship

FOR EACH ROW  --说明创建的是行级触发器

BEGIN

DBMS_OUTPUT.PUT_LINE(‘旧的warship_num值是‘||:old.warship_num

||‘、新的warship_num值是‘||:new.warship_num);

UPDATE soldiers SET warship_num = :new.warship_num

WHERE :old.warship_num = warship_num;

END;

/

触发器已创建

3. 创建一个触发器,限制对订单表lists的修改,

(包括insert,delete,update)的时间范围,即禁止在星期天改变订单信息

CREATE OR REPLACE TRIGGER tr_soldiers_time

BEFORE INSERT OR DELETE OR UPDATE ON soldiers

BEGIN

IF (TO_CHAR(sysdate,‘DAY‘) IN (‘星期六‘, ‘星期日‘))

OR (TO_CHAR(sysdate, ‘HH24:MI‘) NOT BETWEEN ‘09:00‘ AND ‘18:30‘)

THEN

RAISE_APPLICATION_ERROR(-20000, ‘不是上班时间,不能修改soldiers表‘);

END IF;

END;

4. 为soldiers表创建一个触发器,当插入新士兵时显示新士兵的士兵号、士兵名;当更新士兵工资时,显示修改前后士兵工资;当删除士兵时,显示被删除的士兵号、士兵名。

CREATE OR REPLACE TRIGGER trg_soldiers_dml_row

BEFORE INSERT OR UPDATE OR DELETE ON soldiers

FOR EACH ROW

BEGIN

IF INSERTING THEN

--当插入新士兵时显示新士兵的士兵号、士兵名;

DBMS_OUTPUT.PUT_LINE(:new.soldier_num||‘ ‘||

:new.soldiers_name);

ELSIF UPDATING THEN

--当更新士兵工资时,显示修改前后士兵工资;

DBMS_OUTPUT.PUT_LINE(:old.soldiers_sal||‘ ‘||:new.soldiers_sal);

ELSE

--当删除士兵时,显示被删除的士兵号、士兵名。

DBMS_OUTPUT.PUT_LINE(:old.soldier_num||‘ ‘||:old.soldiers_name);

END IF;

END trg_soldiers_dml_row;

.

时间: 2024-10-28 11:29:25

舰队管理系统分析与设计-舰队管理系统分析与设计(Oracle),功能需求,数据字典,软件工程的相关文章

如何使用php设计权限管理数据库

很多网站管理员都想获得php权限,admin,或者root.但如何使用php设置管理员数据库呢? 万事开头难,这里介绍一下. 首先在B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现,而B/S中,浏览器是每一台计算机都已具备的,如果不建立一个完整的权限检测,那么一个"非法用户"很可能就能通过浏览器轻易访问到B/S系统中的所有功能.因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测,让

模块管理常规功能自定义系统的设计与实现(33--权限设计[3])

权限设计(3) 三.字段的只读权限.对于可以修改记录的操作员,可以进一步限制哪些字段对于他是不可修改的.这个功能很少用到,是用户提出来的,我就顺便加了进去.实现这个功能也很简单建立只读字段角色,然后加入模块的字段,最后再将角色加到操作员上即可.前台在解释生成edit form 的时候,将这个字段的只读属性置为true即可.后台Hibernate在新增或保存的时候,可以把只读字段过滤掉,不能保存或不能修改即可. 四.字段的可视权限.有时候某些字段你不希望被某些群组的操作员看到,那么就设置一个隐藏字

模块管理常规功能自定义系统的设计与实现(11--Grid导航设计初步[1])

Grid导航设计(初步)[1] 这一节讲一下Grid导航设计.在前面的章节中有看到Grid导航的样子,那是一个模块的父模块(ManyToOne)对子模块的导航操作.现在对于一个"省份"模块,其没有父模块,我们能对其设计成怎么样的导航呢? 只需一步,将一个字段定义为导航字段.进入"模块字段" 点击修改 保存后,刷新页面.再进入"省份模块"后,可以看到grid的左边就会有一个导航列表. 具选中某个导航值,Grid列表中显示的值就会以此值作为条件进行约

模块管理常规功能自定义系统的设计与实现(32--权限设计[2])

权限设计(2) 二.模块记录的可视权限.通俗的讲哪些记录你能看,哪些记录你不能看,说起来简单,做起来不简单. 先从一个简单的需求说起.对于前面搭建的销售系统如果由一个内勤来处理所有的合同,那么就没有权限设计的问题,把内勤的部门加在"销售部"就可以看到销售一.二.三部的所有合同.但是如果每个销售部有单独的内勤来处理自己部门的销售订单,并且互不干扰,就要设计记录的可视权限了.现在系统里内置了部门的权限.例子中的部门结构如下: 部门编码 部门名称 操作所有记录 操作本级 其他 00 公司  

三十三、Java图形化界面设计——布局管理器之null布局(空布局)

摘自http://blog.csdn.net/liujun13579/article/details/7774267 三十三.Java图形化界面设计--布局管理器之null布局(空布局) 一般容器都有默认布局方式,但是有时候需要精确指定各个组建的大小和位置,就需要用到空布局. 操作方法: 1)       首先利用setLayout(null)语句将容器的布局设置为null布局(空布局). 2)       再调用组件的setBounds(int x, int y, int width,int

三十一、Java图形化界面设计——布局管理器之GridLayout(网格布局)

摘自http://blog.csdn.net/liujun13579/article/details/7772491 三十一.Java图形化界面设计--布局管理器之GridLayout(网格布局) 网格布局特点: l  使容器中的各组件呈M行×N列的网格状分布. l  网格每列宽度相同,等于容器的宽度除以网格的列数. l  网格每行高度相同,等于容器的高度除以网格的行数. l  各组件的排列方式为:从上到下,从左到右. l  组件放入容器的次序决定了它在容器中的位置. l  容器大小改变时,组件

瑞可实验室设计狠抓管理竭诚打造百分百满意的东莞实验室装修设

狠抓管理的瑞可实验室设计更愿意打造百分百满意的东莞实验室装修设计!较东莞实验室装修设计公司,瑞可实验室设计以设计为主导,以工程为依托,本着客户至上,服务第一的理念,提供规范的东莞实验室装修设计,确保东莞实验室装修设计客户百分百满意! 广东瑞可实验室工程有限公司,简称瑞可实验室设计,成立于2001年,注册资金1000万,是东莞知名的民营科技企业.自创办以来,瑞可实验室设计致力于提供商场类室内外装修设计和施工承包服务,项目遍布广东.广西.海南.四川.云南.贵州.湖南.湖北.江西.河南.山东.陕西以及

三十二、Java图形化界面设计——布局管理器之CardLayout(卡片布局)

摘自 http://blog.csdn.net/liujun13579/article/details/7773945 三十二.Java图形化界面设计--布局管理器之CardLayout(卡片布局) 卡片布局能够让多个组件共享同一个显示空间,共享空间的组件之间的关系就像一叠牌,组件叠在一起,初始时显示该空间中第一个添加的组件,通过CardLayout类提供的方法可以切换该空间中显示的组件. 1.  CardLayout类的常用构造函数及方法 2.  使用CardLayout类提供的方法可以切换显

Cassandra与HBase都是被设计用于管理非常大的数据集

在java商城开发中我们都清楚的知道Cassandra与HBase都是NoSQL数据库.总体上看,这意味着用户无法使用SQL数据库.不过,Cassandra使用的是CQL(Cassandra 查询语言),其语法有明显模仿SQL的痕迹.    在jsp商城开发中两者都被设计用于管理非常大的数据集.HBase文件声称一个HBase数据库可以拥有数亿个,甚至是数十亿个行.此外,用户还被建议继续使用关系型数据库.两者都是分布式数据库,不仅仅是在数据的存储方式上,在数据访问方式上亦是如此.客户端可以与集群