【Oracle】实验五 PL_SQL编程

【实验目的】

  1. 熟悉PL/SQL的数据类型和书写规则
  2. 熟悉控制结构和游标的使用
  3. 编写和运行函数、过程和触发器

【实验内容】

编写脚本文件,调试运行脚本文件,并记录结果。

  1. 本地子程序的编写及调试

1、编写一个PL/SQL块,功能用于打印学生信息。整个程序的具体要求如下:

  • 在DECLARE部分完成:
  1. 自定义学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。每个元素均为可变长字符类型
  2. 定义学生信息记录变量stu_record
  3. 编写带一个形参的本地过程:学生信息打印过程PrintStuRecord(x stu_record_type),把形参x定义为(1)中记录类型。这个过程的代码用于实现将形参x的每个元素打印输出(提示:用dbms_output.put_line过程)。
  • 在BEGIN...END部分完成:
  1. 为stu_record变量的各个元素赋值如下:

学号:'2001001'

姓名:'李新'

性别:'m'

籍贯:'黑龙江省哈尔滨市'

学习成绩:'Excellent'

活动成绩:'Good'

  1. 调用本地过程,用stu_record变量作为实参

2、运行这个PL/SQL程序,查看并记录运行结果

  1. 函数的编写及调试
  2. 编写一个函数f_pjgz,有一个数值型参数v_deptno,根据函数调用时输入部门号,来查询scott用户下emp表中该部门所有员工的平均工资,这个平均工资作为函数的返回值。
  3. 用select语句调用该函数,用来查询部门号为10的员工平均工资
  4. 触发器程序的编写及调试
  5. 建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中
  6. 如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,

bookname varchar2(40) not null,

authorname varchar2(10) not null,

publishtime date,

bookprice float)

  1. 建立数据统计表major_stats,包含两个字段:书的总数和作者的总数
  2. 创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中
  3. 在bookinfo表中分别进行插入、删除和更新操作,每种操作执行后再查看bookinfo表和major_stats表中数据的变化

【实验记录】

编写脚本文件,调试运行脚本文件,并记录结果。

  1. 本地子程序的编写及调试

1、编写一个PL/SQL块,功能用于打印学生信息。整个程序的具体要求如下:

  • 在DECLARE部分完成:
  1. 自定义学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。每个元素均为可变长字符类型
  2. 定义学生信息记录变量stu_record
  3. 编写带一个形参的本地过程:学生信息打印过程PrintStuRecord(x stu_record_type),把形参x定义为(1)中记录类型。这个过程的代码用于实现将形参x的每个元素打印输出(提示:用dbms_output.put_line过程)。
  • 在BEGIN...END部分完成:
  1. 为stu_record变量的各个元素赋值如下:

学号:'2001001'

姓名:'李新'

性别:'m'

籍贯:'黑龙江省哈尔滨市'

学习成绩:'Excellent'

活动成绩:'Good'

  1. 调用本地过程,用stu_record变量作为实参

登录SCOTT用户

在桌面创建5_1.sql,用记事本打开,写入代码,完整代码及注释见下图

运行此程序

发现有乱码问题,排查后发现是字符编码错误地设置成了UTF-8,更改这个文件的字符编码为ANSI。同时错误信息"未知的SET选项';'"是因为在set serveroutput on后错误地添加了分号,将其删去。

2、运行这个PL/SQL程序,查看并记录运行结果

成功运行,结果如图所示

  1. 函数的编写及调试
  2. 编写一个函数f_pjgz,有一个数值型参数v_deptno,根据函数调用时输入部门号,来查询scott用户下emp表中该部门所有员工的平均工资,这个平均工资作为函数的返回值。

完整代码如下

  1. 用select语句调用该函数,用来查询部门号为10的员工平均工资

创建函数

调用函数

  1. 触发器程序的编写及调试
  2. 建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中
  3. 如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,

bookname varchar2(40) not null,

authorname varchar2(10) not null,

publishtime date,

bookprice float)

通过查询bookinfo表来查看是否有bookinfo表

发现没有这个表,所以按题干表结构在scott下建立这个表

  1. 建立数据统计表major_stats,包含两个字段:书的总数和作者的总数
  1. 创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中
  1. 在bookinfo表中分别进行插入、删除和更新操作,每种操作执行后再查看bookinfo表和major_stats表中数据的变化

插入操作:

删除操作:

更新操作:

【实验小结】

1.在本实验中,我们通过编写了一个用于打印学生信息的PL/SQL程序、编写并调试一个函数、编写并调试一个触发器,熟悉了PL/SQL编程过程和编程语句;

2.在本实验中遇到了两个问题:

①首先是编码方式问题,需要使用ANSI编码;

②其次是编写触发器时遇到了一个"ora-04901: student2,触发器/函数 不可读"问题,排查后发现是因为一开始写触发器用了一个"for each row",但是我们触发器依附的表是一个动态表,不允许触发器主体对动态表进行查询修改,但这个限制只应用于行级触发器,去掉"for each row"即可完美解决;

相关推荐
九河云4 分钟前
软件开发平台 DevCloud
运维·服务器·数据库·科技·华为云
wind_one11 小时前
7.基础--SQL--DDL-数据类型及案例
数据库·sql
l1t2 小时前
利用DeepSeek改写SQLite版本的二进制位数独求解SQL
数据库·人工智能·sql·sqlite
QT 小鲜肉2 小时前
【QT/C++】Qt定时器QTimer类的实现方法详解(超详细)
开发语言·数据库·c++·笔记·qt·学习
研究司马懿2 小时前
【ETCD】ETCD常用命令
网络·数据库·云原生·oracle·自动化·运维开发·etcd
刘一说3 小时前
深入理解 Spring Boot 中的数据库迁移:Flyway 与 Liquibase 实战指南
数据库·spring boot·oracle
August_._4 小时前
【MySQL】SQL语法详细总结
java·数据库·后端·sql·mysql·oracle
升鲜宝供应链及收银系统源代码服务4 小时前
升鲜宝生鲜配送供应链管理系统---PMS--商品品牌多语言存储与 Redis 缓存同步实现
java·开发语言·数据库·redis·缓存·开源·供应链系统
苦学编程的谢6 小时前
Redis_8_List
数据库·redis·缓存
曹天骄6 小时前
阿里云 DCDN → CDN 无缝切换教程(以 example.com 为例)
数据库·阿里云·云计算