【实验目的】
- 熟悉PL/SQL的数据类型和书写规则
- 熟悉控制结构和游标的使用
- 编写和运行函数、过程和触发器
【实验内容】
编写脚本文件,调试运行脚本文件,并记录结果。
- 本地子程序的编写及调试
1、编写一个PL/SQL块,功能用于打印学生信息。整个程序的具体要求如下:
- 在DECLARE部分完成:
- 自定义学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。每个元素均为可变长字符类型
- 定义学生信息记录变量stu_record
- 编写带一个形参的本地过程:学生信息打印过程PrintStuRecord(x stu_record_type),把形参x定义为(1)中记录类型。这个过程的代码用于实现将形参x的每个元素打印输出(提示:用dbms_output.put_line过程)。
- 在BEGIN…END部分完成:
- 为stu_record变量的各个元素赋值如下:
学号:‘2001001’
姓名:’李新’
性别:‘m’
籍贯:‘黑龙江省哈尔滨市’
学习成绩:‘Excellent’
活动成绩:‘Good’
- 调用本地过程,用stu_record变量作为实参
2、运行这个PL/SQL程序,查看并记录运行结果
- 函数的编写及调试
- 编写一个函数f_pjgz,有一个数值型参数v_deptno,根据函数调用时输入部门号,来查询scott用户下emp表中该部门所有员工的平均工资,这个平均工资作为函数的返回值。
- 用select语句调用该函数,用来查询部门号为10的员工平均工资
- 触发器程序的编写及调试
- 建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中
- 如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,
bookname varchar2(40) not null,
authorname varchar2(10) not null,
publishtime date,
bookprice float)
- 建立数据统计表major_stats,包含两个字段:书的总数和作者的总数
- 创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中
- 在bookinfo表中分别进行插入、删除和更新操作,每种操作执行后再查看bookinfo表和major_stats表中数据的变化
【实验记录】
编写脚本文件,调试运行脚本文件,并记录结果。
- 本地子程序的编写及调试
1、编写一个PL/SQL块,功能用于打印学生信息。整个程序的具体要求如下:
- 在DECLARE部分完成:
- 自定义学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。每个元素均为可变长字符类型
- 定义学生信息记录变量stu_record
- 编写带一个形参的本地过程:学生信息打印过程PrintStuRecord(x stu_record_type),把形参x定义为(1)中记录类型。这个过程的代码用于实现将形参x的每个元素打印输出(提示:用dbms_output.put_line过程)。
- 在BEGIN…END部分完成:
- 为stu_record变量的各个元素赋值如下:
学号:‘2001001’
姓名:’李新’
性别:‘m’
籍贯:‘黑龙江省哈尔滨市’
学习成绩:‘Excellent’
活动成绩:‘Good’
- 调用本地过程,用stu_record变量作为实参
登录SCOTT用户
在桌面创建5_1.sql,用记事本打开,写入代码,完整代码及注释见下图
运行此程序
发现有乱码问题,排查后发现是字符编码错误地设置成了UTF-8,更改这个文件的字符编码为ANSI。同时错误信息“未知的SET选项‘;’”是因为在set serveroutput on后错误地添加了分号,将其删去。
2、运行这个PL/SQL程序,查看并记录运行结果
成功运行,结果如图所示
- 函数的编写及调试
- 编写一个函数f_pjgz,有一个数值型参数v_deptno,根据函数调用时输入部门号,来查询scott用户下emp表中该部门所有员工的平均工资,这个平均工资作为函数的返回值。
完整代码如下
- 用select语句调用该函数,用来查询部门号为10的员工平均工资
创建函数
调用函数
- 触发器程序的编写及调试
- 建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中
- 如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,
bookname varchar2(40) not null,
authorname varchar2(10) not null,
publishtime date,
bookprice float)
通过查询bookinfo表来查看是否有bookinfo表
发现没有这个表,所以按题干表结构在scott下建立这个表
- 建立数据统计表major_stats,包含两个字段:书的总数和作者的总数
- 创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中
- 在bookinfo表中分别进行插入、删除和更新操作,每种操作执行后再查看bookinfo表和major_stats表中数据的变化
插入操作:
删除操作:
更新操作:
【实验小结】
1.在本实验中,我们通过编写了一个用于打印学生信息的PL/SQL程序、编写并调试一个函数、编写并调试一个触发器,熟悉了PL/SQL编程过程和编程语句;
2.在本实验中遇到了两个问题:
①首先是编码方式问题,需要使用ANSI编码;
②其次是编写触发器时遇到了一个“ora-04901: student2,触发器/函数 不可读”问题,排查后发现是因为一开始写触发器用了一个“for each row”,但是我们触发器依附的表是一个动态表,不允许触发器主体对动态表进行查询修改,但这个限制只应用于行级触发器,去掉“for each row”即可完美解决;