第一篇:数据库实验心得
我在sql server 索引基础知识系列中,第一篇就讲了记录数据的基本格式。那里主要讲解的是,数据库的最小读存单元:数据页。一个数据页是8k大小。
对于数据库来说,它不会每次有一个数据页变化后,就存到硬盘。而是变化达到一定数量级后才会作这个操作。这时候,数据库并不是以数据页来作为操作单元,而是以64k的数据(8个数据页,一个区)作为操作单元。
区是管理空间的基本单位。一个区是八个物理上连续的页(即 64 kb)。这意味着 sql server 数据库中每 mb 有 16 个区。
为了使空间分配更有效,sql server 不会将所有区分配给包含少量数据的表。sql server 有两种类型的区:
统一区,由单个对象所有。区中的所有 8 页只能由所属对象使用。
混合区,最多可由八个对象共享。区中八页的每页可由不同的对象所有。
通常从混合区向新表或索引分配页。当表或索引增长到 8 页时,将变成使用统一区进行后续分配。如果对现有表创建索引,并且该表包含的行足以在索引中生成 8 页,则对该索引的所有分配都使用统一区进行。
为何会这样呢?
其实很简单:
读或写 8kb 的时间与读或写 64 kb的时间几乎相同。
在 8 kb 到 64 kb 范围之内,单个磁盘 i/o 传输操作所花的时间主要是磁盘取数臂和读/写磁头运动的时间。
因此,从数学上来讲,当需要传输 64 kb 以上的 sql 数据时,尽可能地执行 64 kb 磁盘传输是有益的,即分成数个64k的操作。
因为 64 kb 传输基本上与 8 kb 传输一样快,而每次传输的 sql server 数据是 8 kb 传输的 8 倍。
我们通过一个实例来看 有and 操作符时候的最常见的一种情况。我们有下面一个表,create table [dbo].[member]([member_no] [dbo].[numeric_id] identity(1,1)not null, [lastname] [dbo].[shortstring] not null, [firstname] [dbo].[shortstring] not null, [middleinitial] [dbo].[letter] null, [street] [dbo].[shortstring] not null, [city] [dbo].[shortstring] not null, [state_prov] [dbo].[statecode] not null, [country] [dbo].[countrycode] not null, [mail_code] [dbo].[mailcode] not null, [phone_no] [dbo].[phonenumber] null, [photograph] [image] null, [issue_dt] [datetime] not null default(getdate()), [expr_dt] [datetime] not null default(dateadd(year,1,getdate())), [region_no] [dbo].[numeric_id] not null, [corp_no] [dbo].[numeric_id] null, [prev_balance] [money] null default(0), [curr_balance] [money] null default(0), [member_code] [dbo].[status_code] not null default(' '))
这个表具备下面的四个索引:
索引名 细节 索引的列
member_corporation_link nonclustered located on primary corp_no
member_ident clustered, unique, primary key located on primary member_no
member_region_link nonclustered located on primary region_no
memberfirstname nonclustered located on primary firstname
当我们执行下面的sql查询时候,select m.member_no, m.firstname, m.region_nofrom dbo.member as mwhere m.firstname like 'k%' and m.region_no > 6 and m.member_no < 5000go
sql server 会根据索引方式,优化成下面方式来执行。
select a.member_no,a.firstname,b.region_nofrom(select m.member_no, m.firstname from dbo.member as m where m.firstname like 'k%' and m.member_no < 5000)a ,--这个查询可以直接使用 memberfirstname 非聚集索引,而且这个非聚集索引覆盖了所有查询列--实际执行时,只需要 逻辑读取 3 次
(select m.member_no, m.region_no from dbo.member as mwhere m.region_no > 6)b
--这个查询可以直接使用 member_region_link 非聚集索引,而且这个非聚集索引覆盖了所有查询列--实际执行时,只需要 逻辑读取 10 次
where a.member_no = b.member_no
不信,你可以看这两个sql 的执行计划,以及逻辑读信息,都是一样的。
其实上面的sql,如果优化成下面的方式,实际的逻辑读消耗也是一样的。为何sql server 不会优化成下面的方式。是因为 and 操作符优化的另外一个原则。
1/26 的数据和 1/6 的数据找交集的速度要比 1/52 的数据和 1/3 的数据找交集速度要慢。
select a.member_no,a.firstname,b.region_nofrom(select m.member_no, m.firstname from dbo.member as mwhere m.firstname like 'k%'--1/26 数据)a,(select m.member_no, m.region_no from dbo.member as mwhere m.region_no > 6 and m.member_no < 5000--1/3 * 1/ 2 数据)bwhere a.member_no = b.member_no
当然,我们要学习sql 如何优化的话,就会用到查询语句中的一个功能,指定查询使用哪个索引来进行。
比如下面的查询语句
select m.member_no, m.firstname, m.region_nofrom dbo.member as m with(index(0))where m.firstname like 'k%' and m.region_no > 6 and m.member_no < 5000go
select m.member_no, m.firstname, m.region_nofrom dbo.member as m with(index(1))where m.firstname like 'k%' and m.region_no > 6 and m.member_no < 5000goselect m.member_no, m.firstname, m.region_nofrom dbo.member as m with(index(membercovering3))where m.firstname like 'k%' and m.region_no > 6 and m.member_no < 5000goselect m.member_no, m.firstname, m.region_nofrom dbo.member as m with(index(memberfirstname, member_region_link))where m.firstname like 'k%' and m.region_no > 6 and m.member_no < 5000go
这里 index 计算符可以是 0,1,指定的一个或者多个索引名字。对于 0,1 的意义如下:
如果存在聚集索引,则 index(0)强制执行聚集索引扫描,index(1)强制执行聚集索引扫描或查找(使用性能最高的一种)。
如果不存在聚集索引,则 index(0)强制执行表扫描,index(1)被解释为错误。
总结知识点:
简单来说,我们可以这么理解:sql server 对于每一条查询语句。会根据实际索引情况(sysindexes 系统表中存储这些信息),分析每种组合可能的成本。然后选择它认为成本最小的一种。作为它实际执行的计划。
成本代价计算的一个主要组成部分是逻辑i/o的数量,特别是对于单表的查询。
and 操作要满足所有条件,这样,经常会要求对几个数据集作交集。数据集越小,数据集的交集计算越节省成本。的项目中,竟然出现了滥用聚集索引的问题。看来没有培训最最基础的索引的意义,代价,使用场景,是一个非常大的失误。这篇博客就是从这个角度来罗列索引的基础知识。
使用索引的意义
索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。
使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。
使用索引的代价
索引需要占用数据表以外的物理存储空间。
创建索引和维护索引要花费一定的时间。
当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度。
创建索引的列
主键
外键或在表联接操作中经常用到的列
在经常查询的字段上最好建立索引
不创建索引的列
很少在查询中被引用
包含较少的惟一值
定义为 text、ntext 或者 image 数据类型的列
heaps是staging data的很好选择,当它没有任何index时
excellent for high performance data loading(parallel bulk load and parallel index creation after load)
excellent as a partition to a partitioned view or a partitioned table
聚集索引提高性能的方法,在前面几篇博客中分别提到过,下面只是一个简单的大纲,细节请参看前面几篇博客。
何时创建聚集索引?
clustered index会提高大多数table的性能,尤其是当它满足以下条件时:
独特, 狭窄, 静止: 最重要的条件
持续增长的,最好是只向上增加。例如:
identity
date, identity
guid(only when using newsequentialid()function)
聚集索引唯一性(独特型的问题)
由于聚集索引的b+树结构的叶子节点必须指向具体数据。如果你要建立聚集索引的列不唯一,并且你指定的创建的聚集索引是非唯一的聚集索引,则会有以下情况:
如果未使用 unique 属性创建聚集索引,数据库引擎 将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。
第二篇:数据库实验心得
没接触数据库的时候总是觉得它比较深奥 或是不可接近的电脑知识,尽管自己对电脑 非常感兴趣,其实还是有些心理上的陌生 感。学习电脑就和我们平时的其它科目学习一样感觉它有永无止境的知识,在这从初接 触电脑时连个电脑的键盘都不敢动到现在 连硬盘都也修理,其中的过程是多么长啊,数据库是我在高中时候听过,到了大学渐渐 了解了些,但就其原理性的内容还不知道,也就是根本就不清楚什么是数据库,只是知 道一个所谓的中国字典里的名词。经过此次 的课程设计,我初步明白了数据库的基本原 理。也已经掌握了数据库的基本知识。我想 对我以后的更深度学习打下了基础。这次课 程设计让我知道了让 vb 连接 sql 的方法。其实就是前台和后台的连接。有了这个思 想,我相信对以后是大有裨益的。
我按照系统工程软件设计的要求,从需求分析,概念设计,总体设计,详细 设计,系统测试等各个步骤,分步完成系统的各项任务,实现了系统中的学生信 息查询,学生信息更新,学生信息添加等模块的功能。在这短短的五天里我收获如下:
1、巩固和加深了对 C#的理解,提高综合运用本课程所学知识的能力。
2、培养了我选用参考书,查阅手册及文献资料的能力。培养独立思考,深 入研究,分析问题、解决问题的能力。
3、通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法和 工程设计方法。根据我在课程设计中遇到的问题,我将在以后的学习当中注意以下几点:
1、认真上好专业实验课,多在实践中锻炼自己。
2、写程序的过程中要考虑周到,严密。
3、在做设计的时候要有信心,有耐心,切勿浮躁。
4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运 用。
5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错 误,以便能节省调试程序的时间
第三篇:数据库实验
实验1.1 使用SQL Server工具(Microsoft SQL Server Management Studio Express)管理数据库 实验内容:
(1)使用SSMS(SQL Server Management Studio)加入实验数据库。(2)使用SSMS可视化建立、修改和删除数据库、表。(3)使用SSMS对数据库进行备份和恢复。
(4)使用SSMS对表进行查询、插入、修改、删除。实验步骤:
(1)加入School数据库。(2)建立Test数据库。
(3)在数据库中建立人员表PERSON(P#,Pname,Page)。更改表设置P#为主键,增加属性Ptype(类型是CHAR,长度是10)。
(4)用SSMS的查询功能(新建查询)对PERSON表进行查询、插入、修改、删除等操作:首先插入两条记录;修改第二条记录;删除第二条记录。(5)备份Test数据库。(6)删除表PERSON。(7)恢复Test数据库。(8)删除Test数据库。
第四篇:数据库实验
3.实验步骤
在学生选课数据库中实现其查询操作,写出T-SQL语句(注:学生选课数据库为前三次实验课所建立的数
据库)
一、简单查询实验
(1)查询选修了课程的学生学号。
(2)查询选修课程号为0101的学生学号和成绩,并要求对查询结果按成绩降序排列,如果成绩相同则按
学号升序排列。
(3)查询选修课程号为0101的成绩在80~90分之间的学生学号和成绩,并将成绩乘以系数0.8输出。
二、连接查询实验
(1)查询每个学生的情况以及他(她)所选修的课程。
(2)查询选修离散散学课程且成绩为90分以上的学生学号、姓名及成绩。
(3)查询每一门课的间接先行课(即先行课的先行课)
三、嵌套查询操作
(1)查询0101课程的成绩高于张林的学生学号和成绩。
(2)查询其他系中年龄小于计算机系年龄最大者的学生。
(3)查询同王洪敏“数据库原理”课程分数相同的学生的学号。
(4)查询选修了全部课程的学生的姓名。
(5)查询与学号为09001103的学生所选修的全部课程相同的学生学号和姓名。
(6)查询至少选修了学号为09001103的学生所选修的全部课程的学生学号和姓名。
四、组合查询和分组查询
(1)查找选修“计算机基础”课程的学生成绩比此课程的平均成绩大的学生学号、成绩。
(2)查询年龄大于女同学平均年龄的男同学姓名和年龄。
(3)列出各系学生的总人数,并按人数进行降序排列。
(5)查询选修计算机基础和离散数学的学生学号和平均成绩。
4、要求
请按题号依次作答,完成在word文档中,写明班级学号姓名,于周日之于周日之前发至xcf7@163.com,独立完成,严禁抄
第五篇:数据库实验答案
实验四
五、实验方法和步骤:
1.向数据库的USERS表空间添加一个大小为10M的数据文件userdata02.dbf。
Alter tablespace users add datafile ‘c:oracleoradataorcluserdata02.dbf’ size 10M;2.向数据库的TEMP表空间添加一个大小为5N的临时数据文件temp02.dbf。
Alter tablespace temp add tempfile’c:oracleoradataorcltemp02.dbf’ size 5M;3.修改userdata02.dbf为自动增长方式,每次增长512k,没有限制大小。
Alter database datafile ‘c:oracleoradataorcluserdata02.dbf’ autoextend on next 512k maxsize unlimited;
4.取消userdata02.dbf的自动增长方式。
Alter database datafile ‘c:oracleoradataorcluserdata02.dbf’ autoextend off;5.将userdata02.dbf大小设置为8MB。
Alter database datafile ‘c:oracleoradataorcluserdata02.dbf’ resize 8M;6.将userdata02.dbf设置为脱机。
Alter database datafile ‘c:oracleoradataorcluserdata02.dbf’ offline;7.将userdata02设置为联机。
Alter database datafile ‘c:oracleoradataorcluserdata02.dbf’ online;8.改变userdata02的名称。
(1)alter tablespace users offline;
(2)将userdata02.dbf重命名为userdata002.dbf;(3)alter tablesace users rename datafile ‘c:oracleoradataorcluserdata02.dbf’,‘c:oracleoradataorcluserdata002.dbf’;(4)alter tablespace users online;
9.查询数据文件信息(包括数据文件动态信息;数据文件详细信息;临时数据文件信息)。(1)select name,file#,status,checkpoint_change# from V$DATAFILE;
(2)select tablespace_name,bytes,autoextensible,file_name from DBA_DATA_FILES;(3)select tablespace_name,file_name,autoextensible from DBA_TEMP_FILES;
实验五 表空间、段、区、块的管理
五、实验方法和步骤:
1.编辑一个脚本文件TEST,脚本文件内容为创建一个永久性的Student表空间,区自动扩展,段采用手动管理方式,并执行脚本文件。
Create tablespace student datafile ‘c:oracleoradataora404orcltbs1_1.dbf’ 2.为数据库的student表空间添加一个大小为10MB的新的数据文件。
Alter tablespace student add datafile ‘c:oracleoradataora404orcltbs1_2.dbf’ size 10M 3.创建一个临时表空间mytemp,并为临时表空间添加一个大小为10MB的临时数据文件。
Create temporary tablespace mytemp tempfile ‘c:oracleoradataora404orcltemp1_1.dbf’ size 20M extent management local uniform size 16M;
Alter tablespace mytemp add tempfile c:oracleoradataora404orltemp1_2.dbf’ size 10M 4.将student表空间新添加的数据文件的大小改为20MB。
Alter database datafile c:oracleoradataora404orcltbs1_2.dbf’ resize 20M 5.将studnet表空间设置为offline;再设置为online。Alter tablespace student offline;Alter tablespace student online;6.将student表空间设置为只读状态。Alter tablespace student read only;7.为student表空间创建一个回退段。
Create rollback segment student_roll tablespace student;8.删除student表空间及其所有内容。
Drop tablespace student including contents;9.查询表空间基本信息。
Select tablespace_name, extent_management,a llocation_type, contents from DBA_TABLESPACE;10.查询表空间数据文件信息。
Select file_name, blocks, tablespace_name from DBA_DATA_FILES;11.统计表空间空闲空间信息。
SELECT TABLESAPCE_NAME “TABLESPACE”, FILE_ID, COUNT(*)“PIECES”, MAX(BLOCKS)“MAXIMUM”, MIN(BLOCKS)“MINIMUM”, AVG(BLOCKS)“AVERAGE”, SUM(BLOCKS)“TOTAL” FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME, FILE_ID;
12.查询表空间空闲空间大小。
SELECT TABLESPACE_NAME, SUM(BYTES)FREE_SPACES FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME;
13.查询scott用户emp表的某个员工元组的物理地址(ROWID)。SELECT ROWID, EMPNO FROM SCOTT.EMP WHERE EMPNO=7369;
实验六 模式对象管理—基础表
五、实验方法和步骤:
1、创建一个表
目标:创建一个名为STUDENT的表,该表有ID(学号)、NAME(姓名)、SEX(性别)、COURSE(课程)、SCORE(成绩)字段,并保存在USER01表空间。
(1)在SQL*PLUS中执行使用CREATE TABLE语句在某一表空间中创建STUDENTS表,并通过INSERT、SELECT、UPDATE、DELETE语句对表进行操作,各举一例。(2)通过OEM控制台新的表,并查看新表情况。Create table student(Id number primary key, Name varchar2(20), Sex char(1),Course varchar2(20), Score number(5,2))tablespace users
Insert into student(id)values(1);Select id from student;
Update student set id=2 where id=1;Delete from student where id=2;
2、创建一个临时表
目标:创建一个名为TEMP01的事务级别临时表,该表有ID(学号)、NAME(姓名)字段,并保存在temp表空间中。
Create global temporary table temp01(id number(2)primary key, name varchar(20))on commit delete rows;
3、修改表
目标:修改STUDENTS表的存储参数;为表分配新的存储空间;添加一个新的列;设置列为无用状态(UNUSED)。
(1)在SQL*PLUS中执行ALTER TABLE语句修改STUDENTS表的存储参数(修改pctfree和pctused分别为20和40)。
Alter table student pctfree 20;Alter table student ptused 40;
(2)在SQL*PLUS中执行ALTER TABLE语句在STUDENTS表分配大小为400KB的新区。Alter table student allocate extent(size 400k);
(3)在SQL*PLUS中执行ALTER TABLE语句在STUDENTS表新增加一个AGE列,列的类型为NUMBER(2)。Alter table student add(age number(2));
(4)在SQL*PLUS中执行ALTER TABLE语句在将STUDENTS表中的AGE设置为无用状态。Alter table student set unused(age);
4、截断表
目标:删除表STUDENTS中的所有记录。
(1)在SQL*PLUS中执行TRUNCATE TABLE语句删除STUDENTS表中的所有记录。Truncate table student;
(2)在SQL*PLUS中执行SELECT语句查看STUDENTS表中的内容。Select * from student;
5、查询ORACLE数据库的模式对象信息
目标:使用管理工具(SQL*PLUS或OEM)获得有关数据库模式对象的有关信息。
(1)用SCOTT帐户登录SQL*PLUS,显示用户,并通过用户视图USER_TABLES、USER_VIEWS、USER_INDEXS、USER_OBJECTS、USER_TRIGGERS、USER_SEQUENCES等模式对象信息。Show user
Select table_name from user_tables;Select view_name from user_views;Select index_name from user_indexes;Select object_name from user_objects;Select trigger_name from user_triggers;Select sequence_name from user_sequence;
(2)使用SCOTT帐户登录数据库,在OME控制台中查看SCOTT用户的各种模式对象信息。
6、给表student表的nane列添加一个唯一值约束,并删除该约束 Alter table student add constraint p_uk unique(name);Alter table student drop drop constraint p_uk;
实验七 模式对象管理—视图
五、实验方法和步骤:
1、创建基础表BOOKS,包含BOOK_ID,数字型,BOOK_NAME,可变长50位,AUTHOR,可变长20位,PRESS可变长50位,Price数字型,PUBLISH_DATE,日期型;并插入10条数据。Create table books(Book_id number primary key, Book_name varchar2(50)not null, Author varchar2(20), Press varchar2(50), Price number, Publishdate date);
2、关系视图
(1)建立关系视图V_BOOKS,包含书名、作者、出版社。Create view v_books as
Select book_id 编号,author 作者,press 出版社
from books;(2)查看视图定义。
Select text from user_views where view_name=’VW_BOOKS’;(3)查看视图内容。
Select * from vw_books;
(4)修改视图,增加一个列出版日期。
Create or replace view VW_BOOKS As
select book_id 编号,author 作者,press 出版社,publishdate 出版日期
from books;(5)向基础表增加一个属性列“价格”,数字型。查看视图的可用性状态。
alter table boks add price int;
Select object_name,status from user_objects where object_name=’VW_BOOKS’ and object_type=’VIEW’;
(6)重新编译V_BOOKS视图。再查看视图的可用性状态
alter view vw_books compile
Select object_name,status from user_objects where object_name=’VW_BOOKS’ and object_type=’VIEW’;(7)删除该视图。
drop view vw_books;
3、内嵌视图
(1)查询价格由高到低处于前三位的书本信息,注意采用内嵌视图的方式实现。
select * from
(select book_id,book_name ,price from books
order by price desc)where rownum<=3;
(2)利用内嵌视图将所有书籍的价格增加10元。
update(select price from books)set price=price+10
实验十 PL/SQL程序结构
五、实验方法和步骤:
1.在SQL*Plus中使用PL/SQL块处理EMP表中职工号7788的职工,如果工资小于5000那么把工资更改为5000。
(1)首先采用SCOTT用户登录;(2)查询7788员工的工资是多少;
(3)定义声明块和执行块,修改该员工工资;(4)再查询该员工工资是多少; SQL>DECLARE
X NUMBER(7,2);BEGIN
SELECT sal INTO x FROM emp WHERE empno = 7788;
IF x < 5000
THEN UPDATE emp SET sal = 5000 WHERE empno = 7788;END IF;END;
2.利用三种循环控制结构向表中插入150条记录。(1)创建一张表,用来记录循环指针的值;
Create table temp_table(num_col number, info_col char(10));(2)利用LOOP循环向表中插入前50条记录; DECLARE
v_counter BINARY_INTEGER :=1;BEGIN
LOOP
INSERT INTO temp_table values(v_counter,’loop index’);
v_counter := v_counter+1;
EXIT WHEN v_counter>50;
END LOOP;END;
(3)利用WHILE循环向表中插入51-100条记录; DECLARE
v_counter BINARY_INTEGER :=1;BEGIN
WHILE v_counter<100 LOOP
INSERT INTO temp_table values(v_counter,’loop index’);
v_counter := v_counter+1;
END LOOP;END;
(4)利用FOR循环向表中插入101-150条记录; DECLARE
v_counter BINARY_INTEGER :=1;BEGIN FOR v_counter IN 101..150 LOOP
INSERT INTO temp_table values(v_counter,’loop index’);
END LOOP;END;
(5)查看表中的信息。
SLELECT * FROM TEMP_TABL
实验十一 游标
五、实验方法和步骤:
1.声明显式游标
声明一个游标用来读取基表EMP中部门号是20且工作为分析员的职工: DECLARE Cursor c1 IS
SELECT ename, sal, hiredate FROM emp WHERE deptno = 20 AND job = 'ANALYST';v_ename VARCHAR2(10);v_sal NUMBER(7,2);v_hiredate date;begin OPEN c1;
FETCH c1 INTO v_ename, v_sal, v_hiredate;CLOSE c1;end;
2.游标的应用
(1)利用游标修改数据,如果EMP中部门号是20,工作为分析员的职工工资小于5000,更改为5000: DECLARE CURSOR c1 IS
SELECT empno, sal, hiredate, rowid
FROM emp WHERE deptno = 20 AND job = 'ANALYST' FOR UPDATE OF sal;emp_record c1%ROWTYPE;BEGIN OPEN c1;LOOP
FETCH c1 INTO emp_record;EXIT WHEN c1%NOTFOUND;IF emp_record.sal <5000 THEN
UPDATE emp set sal = 5000 where empno = emp_record.empno;END IF;END LOOP;CLOSE c1;END;
(2)利用游标,如果部门是SALES,地址不是DALLAS的,地址更改为DALLAS;如果部门不是SALES,地址不是NEW YORK的,地址更改为NEW YORK: DECLARE CURSOR c1 IS SELECT dname, loc FROM dept FOR UPDATE OF loc;Dept_rec c1%ROWTYPE;BEGIN OPEN c1;LOOP
FETCH c1 INTO dept_rec;EXIT WHEN c1%NOTFOUND;
IF dept_rec.dname = 'SALES' AND dept_rec.loc!= 'DALLAS'
THEN UPDATE dept SET LOC = 'DALLAS' WHERE CURRENT OF C1;ELSE IF DEPT_REC.DNAME!= 'SALES' AND DEPT_REC.LOC!= 'NEW YORK' THEN UPDATE dept SET LOC = 'NEW YORK' WHERE CURRENT OF C1;END IF;END LOOP;CLOSE c1;END;
实验十二 存储过程和函数
1.编写一个存储过程,用它显示scott.dept、scott.emp表中各部门的名称、员工总
数以及员工的工资总和和平均工资。
set serverout on;
create or replace procedure outputEMP as begin declare
cursor cEMP is
select dname,count(*),avg(sal),sum(sal)
from scott.emp,scott.dept
where scott.emp.deptno=scott.dept.deptno
group by dname;
d_name varchar2(14);
count_EMP number;
sum_sal number(7,2);
avg_sal number(7,2);
begin
open cEMP;
fetch cEMP into d_name,count_EMP,avg_sal,sum_sal;
while cEMP %found loop
dbms_output.put_line(d_name||','||count_EMP||','||avg_sal||','||sum_sal);
fetch cEMP into d_name,count_EMP,avg_sal,sum_sal;
end loop;
close cEMP;
end;
end outputEMP;2.编写一个函数,用它计算0到指定数字(作为函数输入参数)之间的整数和。set sertverout on;
create or replace function get_sum(maxNUM number)return number as begin
declare sumNUM number;
i number;
begin
sumNUM:=0;
i:=maxNum;
while i>0 loop
sumNUM:=sumNUM+i;
i:=i-1;
end loop;
return sumNUM;
end;end get_sum;
实验十三 触发器
1.编写一个触发器,用它把数据库系统的关闭事件记录到一个表(表结构自己设计)内。Create table shutdown_log(shut_user varchar2(20),shut_time date,shut_action varchar2(20));
create or replace trigger shutdown_record before shutdown on database begin
insert into shutdown_log values(user,sysdate,'关闭数据库');end;
2.编写一个行触发器,把emp表增、删、改操作前后员工的姓名和工资前后变化情况显示处理。create or replace trigger trg_emp_dml_row
Before insert or update or delete on scott.emp
For each row
Begin
If inserting then
Dbms_output.put_line(:new.empno||’ ’||:new.ename);
Elsif updating then
Dbms_output.put_line(:old.sal||’ ’||:new.sal);
Else
Dbms_output.put_line(:old.empno||’ ’||:old.ename);
End if;
End trg_emp_dml_row;