Oracle 实验4(实验报告)-PL_SQL程序设计
ORACLE_PLSQL程序设计
ORACLE_PLSQL程序设计Oracle PL/SQL是一种强大的编程语言,用于开发Oracle数据库的存储过程、触发器、函数和包。
本篇文章将探讨Oracle PL/SQL程序设计的基本概念、语法和功能,以及一些最佳实践和编程技巧。
PL/SQL是Oracle数据库的内置编程语言,它结合了SQL语句和面向过程的语言特性,可以实现复杂的业务逻辑和数据处理。
PL/SQL程序是在数据库服务器上执行的,它可以访问和操作数据库中的数据,并返回结果。
PL/SQL程序由块组成,一个块是一组PL/SQL语句的逻辑单元。
块由关键字BEGIN和END包围,可以包含变量声明、控制结构、异常处理和SQL语句等。
PL/SQL变量是用来存储和操作数据的命名对象,它可以是标量类型(如整数、字符、日期等)、集合类型(如数组、表)或记录类型。
变量可以在块内部声明,并且可以被块内的其他语句引用。
PL/SQL控制结构用于根据条件执行特定的代码块。
常见的控制结构有IF-THEN、IF-THEN-ELSE、CASE等。
这些控制结构可以根据条件执行不同的代码块,增强了程序的灵活性和可读性。
异常处理是PL/SQL程序设计的重要部分。
当出现意外情况或错误时,异常处理机制可以捕获异常并采取相应的措施。
PL/SQL提供了TRY-CATCH结构来处理异常,可以在CATCH块中编写相应的异常处理代码。
PL/SQL还支持存储过程、触发器和函数等数据库对象的定义和使用。
存储过程是一种一次性地执行一系列操作的程序,触发器是在数据库中发生特定事件时自动执行的程序,函数是返回一个值的程序。
这些数据库对象可以帮助我们实现复杂的业务逻辑和数据操作。
在PL/SQL程序设计中,有一些最佳实践和编程技巧值得注意。
首先,要注意代码的可读性和可维护性,良好的命名约定、适当的缩进和注释可以提高代码的可读性。
其次,需要注意异常处理,正确处理和记录异常可以提高程序的稳定性和可靠性。
PLSQL程序设计
包括数值型(如NUMBER)、字符型(如VARCHAR2)、 日期型(如DATE)等。
01
集合数据类型
包括表、数组和集合,用于存储多个值。
02
03
自定义数据类型
使用COMMIT语句可以提交事务,将所有未提交的更改永久保存到数据库中。
感谢您的观看
THANKS
循环读取
使用循环结构(如WHILE循环)逐行读取游标中的数据。
异常处理
在读取游标数据时,应处理可能出现的异常,以确保程序的健壮 性。
游标的关闭
关闭游标
使用CLOSE语句关闭游标,释放与 游标相关的资源。
清理资源
关闭游标后,应释放所有与游标相关 的变量和资源,以避免内存泄漏。
06
PL/SQL事务处理
BEFORE触发器
在指定的事件(如INSERT、UPDATE或DELETE)之前执行的操作。
AFTER触发器
在指定的事件之后执行的操作。
INSTEAD OF触发器
用于视图,当对视图进行修改操作时,触发器中的操作替代了原本 的修改操作。
触发器的应用场景
数据完整性维护
触发器可用于确保数据的完整性,例如, 在更新员工工资时自动计算并更新员工
的总收入。
条件约束
触发器可用于实现复杂的业务规则, 例如,限制某些用户不能删除其他用
户的记录。
自动日志记录
触发器可以在数据修改时自动记录操 作日志,便于跟踪数据变更历史。
数据转换
触发器可以在数据修改时自动进行数 据转换或格式化,例如,将日期字段 自动转换为特定的格式。
05
PL SQL编程 Oracle数据库实验报告
PL/SQL编程【实验目的】1.熟悉PL/SQL的数据类型和书写规则2.熟悉控制结构和游标的使用3.编写和运行函数、过程和触发器【实验内容】编写脚本文件,调试运行脚本文件,并记录结果。
1.在SQL*Plus中编写一个PL/SQL块,功能用于打印学生信息在DECLARE部分完成:(1)建立学生信息记录类型stu_record_type,包括学号,姓名,性别,籍贯,学习成绩和活动成绩。
均为可变长字符类型(2)编写本地子过程:学生信息打印过程PrintStuRecord,把(1)中定义的记录类型作为参数(3)定义学生信息记录变量stu_record在BEGIN…END部分完成:(1)为stu_record变量的各个元素赋值如下:学号:‘2001001’姓名:’李新’性别:‘m’籍贯:‘黑龙江省哈尔滨市’学习成绩:‘Excellent’活动成绩:‘Good’(2)对该变量的调用打印过程,输出到屏幕2.建立对bookinfo表的DML触发器,一旦bookinfo表发生了任何变化,立即触发,对bookinfo表的数据进行统计,结果存储在数据统计表中(1)如果没有则建立bookinfo表,选择建立在scott用户下,表结构为(bookno varchar2(36) Primary key,bookname varchar2(40) not null,authorname varchar2(10) not null,publishtime date,bookprice float)(2)建立数据统计表major_stats,包含两个字段:书的总数和作者的总数(3)创建触发器UpdateMajorStats,完成在bookinfo表中插入、删除和修改记录之后,对bookinfo表进行统计,结果存储在(2)建立的major_stats表中(4)在bookinfo表中插入、删除和更新信息,再查看major_stats表中数据的变化【实验结论】编写脚本文件,调试运行脚本文件,并记录结果。
Oracle数据库实验-PLSQL游标、过程、函数、包的使用
Oracle数据库实验-PLSQL游标、过程、函数、包的使用Oracle数据库基础实验5 PL/SQL游标、过程、函数、包的使用【实验学时】2学时【实验目的】1.了解PL/SQL语言中显式游标和隐式游标的概念和属性。
2.了解显式游标和隐式游标的差异。
3.掌握PL/SQL中cursor for循环的使用方法。
4.学会在PL/SQL程序中使用游标来解决实际问题。
5.学会在PL/SQL程序中进行异常处理的方法。
6.练习在PL/SQL中自定义异常。
7.理解过程和函数的作用。
8.学会编写过程、函数、包,并加以调用。
【实验内容】1.用显式游标编写程序,程序的功能是:计算每一个部门的平均工资。
注意异常的处理(例如,分母为0的异常)。
已写入文件afiedt.buf1 declare2 cursor c_dept is select * from dept order by deptno;3 cursor c_emp(p_dept emp.deptno%type)is selectename,sal from emp where deptno=p_dept4 order by ename;5 r_dept dept%rowtype;6 v_ename emp.ename%type;7 v_salary emp.sal%type;8 v_tot_salary emp.sal%type;9 begin10 open c_dept;11 loop12 fetch c_dept into r_dept;13 exit when c_dept%notfound;14dbms_output.put_line('department:'||r_dept.deptno||'-'||r_de pt.dname);15 v_tot_salary:=0;16 open c_emp(r_dept.deptno);17 loop18 fetch c_emp into v_ename,v_salary;19 exit when c_emp%notfound;20dbms_output.put_line('name:'||v_ename||'salary:'||v_salary);21 v_tot_salary:=v_tot_salary+v_salary;22 end loop;23 close c_emp;24 dbms_output.put_line('total salary fordept:'||v_tot_salary);25 end loop;26 close c_dept;27* end;SQL> /PL/SQL 过程已成功完成。
Oracle SQL PLSQL实验
实验1SQL*Plus的使用和基本SELECT语句实验要求(1)掌握SQL*Plus的基本使用(2)掌握SELECT语句的简单用法。
实验条件自我实践实验时间大约60分钟1.练习1 FOLLOW ME●时间20分钟●实验步骤(1)观看第1章教学视频。
(2)实践视频中的实例。
2.练习2●时间40分钟●实验步骤(1)登录到SQL*Plus,初始用户名为:SCOTT,口令为TIGER。
(2)分别显示EMP、DETP、SALGRADE表结构,并察看表中的数据。
(3)创建一个查询显示每个雇员的姓名、工作、受雇日期及雇员编号,并且要将雇员编号作为第一列显示。
最后将该SQL语句保存成文件p1q1.sql,并执行该脚本文件。
(4)将脚本文件p1q1.sql调取到SQL缓冲区,并将列标题设置为Emp #,Employee,Job及Hire Date,将该SQL语句保存成文件p1q2.sql,最后返回查询结果。
思考练习题1.SQL*Plus命令是用于访问数据库的吗?2.下面的SELECT语句能成功执行吗?SQL>SELECT ename,job,sal Salary2FROM emp;3.下面的语句有3处错误,请纠正它们。
SQL>SELECT empno,ename2Salary x 12 ANNUAL SALARY3FROM emp;4.创建一个查询从EMP表中检索出不重复的工作名称。
5.用一个逗号和一个空格将姓名和工作连接后作为一个整体输出,显示的列标题为Employee and Title。
6.创建一个查询,用逗号将表中所有字段的信息连接作为一个整体输出,输出的列标题为THE_OUTPUT。
实验2使用WHERE和ORDER BY子句实验要求(1)掌握WHERE子句的用法。
(2)掌握ORDER BY子句的用法。
实验条件自我实践实验时间大约60分钟1.练习1FOLLOW ME●时间20分钟●实验步骤(1)观看第2章教学视频。
oracle综合性实验指导
湖南科技学院综合性实验指导书实验名称:PL/SQL编程实验项目性质:综合性所涉及课程:Oracle数据库计划学时:4一、实验目的(1)熟练掌握PL/SQL程序设计的基本知识。
(2)熟练掌握PL/SQL中控制结构的使用。
具体包括选择结构语句(IF语句和CASE语句),循环结构(四种循环结构)。
(3)熟练使用PL/SQL中系统函数。
(4)掌握PL/SQL中异常处理语句的使用(5)掌握PL/SQL中SELECT语句和DML语句的综合运用。
二、实验内容及步骤1.创建用户,指定密码、表空间。
用户名命名以本人姓名的缩写+‘_’+学号最后两位。
2.为该用户授予sysdba、connect、resource权限。
3.以本人的用户身份登录。
4.练习选择结构语句的使用方法。
1、条件语句IF 语法:IF <条件表达式> THEN<执行语句> …… <执行语句n>[ELSIF <条件表达式> THEN<执行语句> …… <执行语句n>……ELSE<执行语句>]END IF;2、分支语句CASE 语法:CASE <变量>WHEN <表达式1> THEN 值1WHEN <表达式2> THEN 值2……WHEN <表达式n> THEN 值nELSE 值n + 1END;例1:声明一个整型变量Num,使用IF语句判断Num变量是正数、负数或0。
SET ServerOutput ON;DECLARENum INTEGER := -11;BEGINIF Num < 0 THENdbms_output.put_line('负数');ELSIF Num >0 THENdbms_output.put_line('正数');ELSEdbms_output.put_line('0');END IF;END;例2、使用CASE语句根据给定的整数输出对应的星期值:SET ServerOutput ON;DECLAREvarDAY INTEGER := 3;Result V ARCHAR2(20);BEGINResult := CASE varDA YWHEN 1 THEN '星期一'WHEN 2 THEN '星期二'WHEN 3 THEN '星期三'WHEN 4 THEN '星期四'WHEN 5 THEN '星期五'WHEN 6 THEN '星期六'WHEN 7 THEN '星期七'ELSE '数据越界'END;dbms_output.put_line(Result);END;5.练习循环结构语句的使用方法。
《Oracle数据库》实验报告
实验二Oracle数据库开发环境下PL/SQL编程(2学时)【实验目的】(1)掌握PL/SQL 的基本使用方法。
(2)在SQL*PLUS环境下运行PL/SQL的简单程序。
(3)应用PL/SQL 解决实际问题【实验内容与步骤】一、实验内容:1、用PL/SQL实现:输入eno的值,显示emp表中对应记录的内容。
2、用PL/SQL完成:读入三个数,计算并输出它们的平均值及三个数的乘积。
3、对职工表emp中的雇员SCOTT提高奖金,若工种为MANAGER,则奖金提高其原来的20%;若工种为SALESMAN,则奖金提高其原来的15%;若工种为ANALYST,则奖金提高其原来的10%,其它都按原来的7%提高。
4、用PL/SQL块实现下列操作公司为每个职工增加奖金:若职工属于30号部门,则增加$150;若职工属于20号部门,则增加$250;若职工属于10号部门,则增加$350。
(提示:游标请自行阅读相关内容)DECLAREaddcomm m%type;CURSOR emp_cursor IS select deptno from emp;BEGINFOR emprec IN emp_cursor LOOPIF emprec.deptno=30 THEN addcomm:=150;ELSIF emprec.deptno=20 THEN addcomm:=250;ELSIF emprec.deptno=10 THEN addcomm:=350;END IF;Update empset comm=comm+ addcomm where deptno= emprec.deptno;END LOOP;COMMIT WORK;END;实验三PL/SQL触发器和存储过程(2学时)【实验目的】(1)了解触发器的类型。
(2)掌握PL/SQL触发器的使用方法。
(3)了解存储过程的使用方法。
(4)掌握存储过程的使用方法。
【实验内容】实验内容:1、编写一个数据库触发器,当任何时候某个部门从dept表中删除时,该触发器将从emp 表中删除该部门的所有雇员。
实验四 PLSQL高级编程
实验四PL/SQL高级编程开发语言及实现平台或实验环境:Oracle 11g实践目的(1) 掌握游标、存储过程、存储函数、包、触发器的基本作用。
(2) 掌握存储过程、存储函数、包、触发器的建立、修改、查看、删除操作。
实验要求(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 掌握游标、存储过程、存储函数、包、触发器的命令。
实验内容1.创建存储过程(1) 将下列的未命名的PL/SQL,转换成存储过程,存储过程名自己设定,注意比较未命名的PL/SQL 与命名的PL/SQL 的差别,如没有where current of 是什么情况。
declarecursor emp_cursor is select * from emp where deptno=10 for update;beginfor emp_record in emp_cursor loopdbms_output.put_line(emp_record.sal);update emp set sal=sal*1.1 where current of emp_cursor;end loop;end;/执行sal=sal*1.1语句时,只对当前游标所指向的对象进行操作。
执行sal=sal*1.1语句时,对所有找到的游标对象进行操作。
(2)(3)任选一个(2) 创建存储过程“dept_count_pro_学号后四位”,实现显示scott方案中dept 表中各本门编号与名称,并显示对应部门的员工姓名和工资。
显示结果可如下图,也可自己设计:(3) 创建存储过程“num_pro_学号后四位”,通过传入参数传入3个数,完成3 个数的从小到大排序,通过 3 个传出参数保存排序后的 3 个数,并执行该存储过程,显示排序结果。
(4)通过user_source 数据字典中查看存储过程。
2.创建函数(1)(2)任选一个(1) 创建存储函数“emp_fun_学号后四位”,通过传入参数传入员工的编号,根据传入的员工编号,检查该员工是否存在。
PL/SQL程序设计
PL/SQL程序设计PL/SQL是一种数据库编程语言,广泛应用于Oracle数据库管理系统中。
它是SQL的一种扩展,添加了过程性编程的特性,允许开发者创建更复杂、可重用的程序逻辑。
PL/SQL程序设计可以分为以下几个方面:1.PL/SQL的基本概念:PL/SQL是过程性语言和SQL结构的结合。
它使用块的概念,一个块由一个可选的声明部分、一个执行部分和一个可选的异常处理部分组成。
PL/SQL程序可以包含变量、常量、游标和异常处理等元素。
2.变量和数据类型:在PL/SQL中,可以通过声明变量来存储和操作数据。
PL/SQL中支持多种数据类型,包括基本的整型、字符型、日期型等,还可以自定义记录类型和表类型。
使用变量可以在程序中存储临时数据,进行运算和逻辑判断。
3.控制结构:PL/SQL支持多种控制结构,包括条件语句、循环语句和异常处理语句。
条件语句可以根据一些条件来执行不同的操作。
循环语句可以重复执行一段代码,直到满足退出条件为止。
异常处理语句用于捕获和处理运行时错误,保证程序的健壮性。
4.子程序:PL/SQL中的子程序可以是存储过程、函数或触发器。
存储过程是一段可重用的代码块,它可以在数据库中存储和调用。
函数是一个具有返回值的子程序,可以在SQL语句中使用。
触发器是与表相关联的特殊存储过程,当满足特定的条件时自动触发。
5.游标和异常处理:PL/SQL中的游标用于处理查询结果集。
游标可以使用循环语句来遍历结果集,并进行相应的操作。
异常处理是PL/SQL的一大特点,它可以有效地捕获和处理运行时错误。
在异常处理部分,可以指定对应不同类型错误的处理方式,例如日志记录、回滚事务等。
6.包和包体:PL/SQL中的包是一种逻辑上的封装,它可以包含变量、常量、游标和子程序等。
包体是包的实现部分,声明和定义了包中的各个元素。
使用包可以将相关的数据和逻辑组织在一起,提供更好的可维护性和可重用性。
7.异常处理和日志记录:在实际的PL/SQL开发中,异常处理是非常重要的。
Oracle数据库实验-PLSQL块结构,条件、循环语句的使用
Oracle数据库基础实验4 PL/SQL块结构,条件、循环语句的使用【实验学时】2学时【实验目的】1.学习匿名PL/SQL块的基本结构。
2.了解PL/SQL的基本数据类型。
3.掌握PL/SQL中变量和常量的定义方法。
4.学会在PL/SQL程序中使用复合数据类型:记录和集合。
5.学会使用select…into…语句返回一行数据。
6.练习在PL/SQL中使用DML语句和动态SQL语句。
7.熟练掌握PL/SQL中的选择和循环语句的使用。
【实验内容】1.定义一个PL/SQL块,向屏幕输出hello world!。
SQL> ed已写入文件afiedt.buf1 declare2 begin3 dbms_output.put_line('hello,world');4 exception5 when others then6 dbms_output.put_line('error');7 raise;8* end;SQL> /hello,worldPL/SQL 过程已成功完成。
2.定义一个PL/SQL块,将输入的字符串中大小写相互转换后向屏幕输出。
例如,输入abDCe,输出ABdcESQL> ed已写入文件afiedt.buf1 declare2 str1 varchar2(20):='&str1';3 str2 varchar2(2);4 str3 varchar2(20);5 len number(10);6 leng number(10);7 begin8 len:=1;9 leng:=length(str1);10 while len<=leng loop11 str2:=substr(str1,len,1);12 if str2>='a' and str2<='z' then13 str3:=str3||upper(str2);14 elsif str2>='A' and str2<='Z' then15 str3:=str3||lower(str2);16 end if;17 len:=len+1;18 end loop;19 dbms_output.put_line(str3);20* end;SQL> /输入str1 的值: ehhrfEdsd原值2: str1 varchar2(20):='&str1';新值2: str1 varchar2(20):='ehhrfEdsd';EHHRFeDSDPL/SQL 过程已成功完成。
实验四 PLSQL编程
实验四 PL/SQL编程一、实验目的及要求(1) 掌握PL/SQL块结构、PL/SQL的基本语法、PL/SQL的控制结构。
(2) 掌握PL/SQL块中使用复合数据类型和游标的方法。
(3) 掌握PL/SQL异常处理技术。
(4) 掌握存储过程、存储函数、触发器高级数据库对象的基本作用。
(5) 掌握存储过程、存储函数、触发器的建立、修改、查看、删除操作。
二、实验主要内容(1) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(2) 记录利用SQL Plus或PL/SQL Developer编写、执行PL/SQL程序的命令。
(3) 记录执行命令和操作过程中遇到的问题及解决方法,注意从原理上解释原因。
(4) 记录利用企业管理器管理存储过程、存储函数、触发器的方法。
(5) 记录利用SQL Plus和PL/SQL Developer管理存储过程、存储函数、触发器的命令。
三、实验仪器设备在局域网环境下,有一台服务器和若干台客户机。
服务器成功安装Oracle 11g 数据库服务器(企业版),客户机成功安装Oracle 11g客户端软件,网络服务配置正确,数据库和客户端正常工作。
四、实验步骤1.在SQL*Plus中使用PL/SQL块处理EMP表中职工号7788的职工,如果工资小于3000那么把工资更改为3000:2.无参数的存储过程3.带输入参数的存储过程:解雇给定职工号的职工,并调用proc_execution:SQL>EXECUT fire_emp(7654)PL/SQL procedure successfully completed.存储过程删除了职工号7654的职工。
4.带输入输出的存储过程查询EMP中给定职工号的姓名、工资和佣金。
SQL> VARIABLE emp_name varchar2(15);SQL> VARIABLE emp_sal number;SQL> VARIABLE emp_comm number;SQL> EXECUTE query_emp(7654,:emp_name, :emp_sal, :emp_comm);PL/SQL procedure successfully completed.SQL> PRINT emp_name;EMP_NAME-------------------MARTIN12345.用Function查询出EMP中给定职工号的工资:SQL>VARIABLE emp_sal numberSQL>EXECUTE :emp_sal := get_sal(7654)PL/SQL procedure successfully completed.SQL>PRINT emp_salEMP_SAL-------------------1250• 1• 2• 3• 4• 5• 6 6.用异常处理完善程序如例3中:解雇给定职工号的职工,并调用proc_execution:SQL>EXECUT fire_emp(7654)如果职工号7654的职工不存在则出错。
oracle 第4章plsql编程
第二步:声明游标 游标的声明也放在declare块中,由标标名和希望执行的查询语句组 成 语法: CURSOR cursor_name IS select_statement 其中:cursor_name为游标名,select_statement为可执行的查询
语句
如: declare ..... CURSOR v_cursor_dept IS select * from scott.dept
示例:使用for in 枚举员工信息
declare cursor cursor_emp is select * from scott.emp; -- 1 定义游标 begin for m in cursor_emp -- 这行代码 包含了 打开游标 提取游标 loop dbms_output.put_line(m.ename||' '||m.empno); end loop; end;
控制语句
条件控制语句 if 条件 then 执行语句.... end if; if 条件 then 执行语句1.... elsif 条件 then 执行语句2.... end if;
if 条件 then 执行语句1.... else 执行语句2.... end if;
控制语句
循环控制语句 loop 执行语句.... [EXIT|EXIT When (条件)] end loop; while 条件 loop 执行语句.... end loop; for counter in [ reverse] value1..value2 loop 执行语句.... end loop; (reverse:对值从大到小执行循环)
游标的使用
第三步:打开游标 打开游标在begin(即PL/SQL的执行块中)的执行段中,打开游标 使用open语句 语法: OPEN cursor_name 其中:cursor_name为游标名
Oracle实验四上:PL SQL程序设计:控制结构和嵌入式SQL
《数据库开发技术》实验四
实验题目:PL/SQL程序设计:控制结构和嵌入式SQL
日期
2015-11-15
班级
计算机1301
姓名
实验环境:Win10+Oracle11g
实验内容与完成情况(记录所有的实验过程):
1.通过CASE语句判断7788雇员的工资等级后输出,工资等级划分条件是:3000(含)以上为高,1500(含)至3000为中,低于1500为低。
Sql语句:
set serveroutput on
declare
v_sum number;
v_iniNum number;
begin
v_sum :=ቤተ መጻሕፍቲ ባይዱ0;
v_iniNum := 12;
loop
v_sum := v_sum+v_iniNum;
v_iniNum := v_iniNum + 20;
exit when v_iniNum > 152;
/
效果截图:
方式二:
set serveroutput on
declare
v_nnumber;
begin
For v_n in 32..126 loop
Insert intod_asc(n, a )
Values
(v_n,CHR(v_n));
End loop;
end;
/
效果截图:
附加题:
*用PL/SQL的FOR循环输出以下实心三角形:
else '低'
end
into v_grade
PLSQL程序设计(Oracle)_教程宋红康_oracle_sql_plsql
PLSQL程序设计(Oracle)_教程宋红康_oracle_sql_plsql 学完了,做个⼩总结,也当做复习⼀下掌握Oracle数据库,阅读起来会顺畅⼀些什么是PL/SQL?PL/SQL全称Procedure Language & Structured Query LanguagePL/SQL是Oracle对sql语⾔的过程化扩展指在SQL命令语⾔中增加了过程处理语句(如分⼦、循环等),使SQL语⾔具有过程处理能⼒(就是对SQL语⾔储存过程语⾔的扩展) PL/SQL程序结构declare --程序的声明部分(声明变量,声明游标,声明例外等)begin --程序的执⾏部分(打印输出,if,循环等)exception --异常处理机制(plsql程序遇到错误对⾃动停⽌运⾏,提前写好exception语句则会正常执⾏完毕) --如没有异常处理机制通常省略这段代码(学习过程中基本不会⽤到)end;变量声明规则:⽰例: Hello Worldset serveroutput on; --每次第⼀次使⽤需要这条命令开启plsql程序declare--声明部分,⽤于声明某些变量,记录类型,游标等begin--程序的执⾏部分,dbms_output.put_line('Hello World');end;⽰例: 查询员⼯号(employe_id)为100的员⼯的⼯资(salary)declare--声明变量v_sal number(8,2);begin--select语句;格式: select...into...select salary into v_sal from employees where employee_id =100;--打印输出结果dbms_output.put_line(v_sal);end;。
PLSQL程序设计
PLSQL程序设计PL/SQL(Procedural Language/Structured Query Language)是一种编程语言,被广泛用于Oracle数据库管理系统中。
它结合了SQL的优势和过程化编程的能力,允许开发人员编写复杂的程序来处理和管理数据。
PL/SQL的程序设计主要包括声明变量、控制结构、循环语句、异常处理和存储过程等。
首先,PL/SQL允许开发人员在程序中声明变量,这些变量可以存储数据,以供程序使用。
在声明变量之后,可以对其进行赋值和引用。
PL/SQL支持多种数据类型,包括数字、字符、日期和布尔值等。
其次,PL/SQL提供了控制结构,可以根据不同的条件来执行不同的代码块。
常用的控制结构包括条件语句(IF-THEN-ELSE)、CASE语句和循环语句(FOR、WHILE)。
这些结构使得开发人员可以根据需要来控制程序的执行流程。
异常处理是PL/SQL的一个重要特性。
通过使用TRY-CATCH块,可以捕捉和处理程序中可能发生的异常。
开发人员可以定义自己的异常,并根据需要采取适当的措施来处理异常,例如记录日志、回滚事务等。
存储过程是PL/SQL的一个重要组成部分。
它允许开发人员将一组SQL语句封装为一个可重复使用的块,并且可以在数据库中进行存储,以便其他程序可以调用。
存储过程在提高性能、简化复杂操作和增强数据安全性方面具有广泛的应用。
此外,PL/SQL还提供了许多其他功能,如游标(用于处理查询结果集)、函数(用于返回单个值)和触发器(用于在数据发生变化时执行相应的操作)等。
这些功能使得开发人员可以更高效地处理和管理数据。
总结起来,PL/SQL是一种强大的程序设计语言,适用于处理和管理Oracle数据库中的数据。
它结合了SQL的优势和过程化编程的能力,在开发数据库应用程序时具有很大的优势。
通过灵活运用PL/SQL的各种功能,开发人员可以编写高效、可靠和安全的程序。
(完整word版)实验二 PL SQL编程实验报告(word文档良心出品)
湖南第一师范学院信息科学与工程系实验报告课程名称:ORACLE数据库系统及应用成绩评定:实验项目名称:实验二:PL/SQL编程指导教师:学生姓名:学号:专业班级:实验项目类型:设计实验地点:实验时间:年月日一、实验目的与要求:1、掌握PL/SQL 程序设计的基本知识;2、掌握PL/SQL 中SELECT 语句和DML 语句的正确使用方法;3、掌握存储过程、函数、游标、触发器与包的创建与使用。
二、实验环境:(硬件环境、软件环境)1.硬件环境:奔ⅣPC。
2.软件环境:Windows2000 操作系统,Oracle 9i。
三、实验内容:(原理、操作步骤、程序代码等)任务:1、编写存储过程,根据用户输入的部门编号实现在PL/SQL 中逐行显示emp 表中该部门员工的工资级别。
工资级别是:当工资为空时,为空,工资在1000 元以下的为‘低’,在1000 和3000之间的为‘中’,高于3000 元的为‘高’。
要有异常处理(该部门编号不存在)。
create or replace procedure review_ep(v_deptno in dept.deptno%type)iscursor c1is select * from empwhere emp.deptno=v_deptno;record1emp%rowtype;deptno_not_found exception;beginopen c1;fetch c1into record1;if(not c1%found) then raise deptno_not_found;end if;while c1%found loopif nvl(record1.sal,0)<1000thendbms_output.put_line(record1.ename||'工资低');elsif nvl(record1.sal,0)<3000thendbms_output.put_line(record1.ename||'工资中等');elsedbms_output.put_line(record1.ename||'工资高');end if;fetch c1into record1;end loop;close c1;exception when deptno_not_found thendbms_output.put_line('deptno not found');end;2.有这么一张表temp1,他只有一个number(8)的字段no,由于在创建表时忘记设置主键约束,导致表中有很多重复的记录。
Oracle数据库 实验报告
在SQL*PLUS或PL/SQL Developer工具中编写PL/SQL的简单程序,熟悉PL/SQL的编程环境和代码结构。实现与Oracle数据库交互,并捕获和处理常见系统异常和用户自定义异常。
3.主要仪器设备及软件
1)PC
2)ORACLE数据库
-------------------------------------------------------------------------
实现下面功能:
使用游标实现:将某门课程高于平均分的学生的姓名,课程名,成绩格式化输出。
3.主要仪器设备及软件
1)PC
2)ORACLE数据库
-------------------------------------------------------------------------
实验一 了解ORACLE环境,使用ORACLE数据库实用工具
( 验证性实验 4学时)
1.目的要求:
了解ORACLE数据库的各个常用工具软件
2.实验内容:
在ORACEL数据库下使用SQL*PLUS ,SQL*PLUS Worksheet,PL/SQL Developer工具,企业管理器等实用工具与Oracle交互。并在企业管理器中观察ORACLE的底层存储原理。在PL/SQL Developer中书写简单的SQL语言。
3.主要仪器设备及软件
1)PC
2)ORACLE数据库
-------------------------------------------------------------------------
实验六 触发器,序列及同义词
( 验证性实验 6学时)
PL/SQL程序设计
PL/SQL程序设计PL/SQL是Oracle数据库中的编程语言,用于在数据库中创建存储过程、函数、触发器等数据库对象,以提供更高级的数据处理和业务逻辑功能。
下面将介绍一些PL/SQL的基本概念和用法,并通过示例演示其程序设计能力。
PL/SQL是一种结合了SQL和Procedural Language的编程语言,它允许在数据库中编写逻辑代码。
PL/SQL包括了一些基本的语法元素,如条件判断、循环语句、异常处理等,还可以使用SQL语句进行数据查询和数据操作。
PL/SQL程序有两种类型:匿名块和命名块。
匿名块是一段临时的、不可重复使用的代码,而命名块则是一段命名的代码,可以在其它代码中多次调用。
下面是一个例子,演示了如何使用PL/SQL创建一个匿名块:```plsqlDECLAREv_name VARCHAR2(100) := 'John';BEGINDBMS_OUTPUT.PUT_LINE('Hello, ' , v_name , '!');END;```在上面的例子中,我们声明了一个变量v_name,并将其赋值为'John'。
然后使用DBMS\_OUTPUT.PUT\_LINE函数将Hello, John!打印到控制台。
除了匿名块,PL/SQL还可以创建存储过程、函数和触发器等可重复使用的数据库对象。
下面是一个示例,演示了如何使用PL/SQL创建一个简单的存储过程:```plsqlCREATE OR REPLACE PROCEDURE get_employeep_employee_id IN NUMBER,p_department_id OUT NUMBER,p_salary OUT NUMBERISBEGINSELECT department_id, salary INTO p_department_id, p_salary FROM employeesWHERE employee_id = p_employee_id;END;```在上面的例子中,我们创建了一个名为get\_employee的存储过程。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学期Oracle数据库应用技术实验报告选课序号:班级:学号:姓名:指导教师:***成绩:2017年月日目录1.实验目的 (1)2.实验内容 (1)2.1 触发器设计 (2)2.2 存储过程、自定义函数设计 (2)2.3 程序包设计 (3)3.实验步骤 (3)3.1 创建表空间RESTAURANT,创建用户DINER (3)3.2 创建餐饮系统数据库的所有表,并向各表插入演示数据 (4)3.3 完成【实验内容】中的触发器、存储过程、函数和程序包等功能设计,将程序脚本保存到文本文件Source.sql中 (7)4.实验总结 (13)PL/SQL程序设计1.实验目的◆掌握PL/SQL程序设计基本技巧,包括基本数据类型、表类型、数组类型、匿名程序块、控制语句、PL/SQL中使用SQL语句、游标、错误处理等。
◆熟悉和掌握PL/SQL中关于存储过程、函数、包和触发器程序设计技术。
2.实验内容实验平台:PL/SQL Developer或Oracle的其它客户端管理工具。
某餐饮系统数据库(加粗字段为主键,斜体字段为外键),请创建如下各数据表,并实现如下存储过程、函数、包和触发器等功能设计,将程序脚本保存到文本文件Source.sql中:(1)菜肴类别表MK(菜肴类别编号MKid,菜肴类别名称MkName),菜肴类别名称:鱼类、蔬菜类、凉菜类、肉类、主食类和酒水类等。
(2)菜单信息表MList(菜肴编号Mid,菜肴名称Mname,菜肴类别MKid,菜肴单价Mprice,菜肴成本单价Mcost,更新日期Mdate)。
(3)餐台类别表DK(餐台类别编号DKid,餐台类别名称DkName),餐台类别:包间和散台等。
(4)餐台信息表Dinfo (餐台编号Did,餐台名称Dname,餐台类别DKid,座位数Dseats,更新日期Ddate)。
(5)消费单主表C (消费单号Cid,餐台编号Did,消费开始时间StartTime,结账时间EndTime,消费金额合计Smoney,盈利金额合计SPsum),其中,消费金额合计=消费单明细表CList中该消费单号的所有消费记录的消费金额的合计,即SUM(消费金额)或SUM(菜肴单价×消费数量),盈利金额合计=消费单明细表CList中该消费单号的所有消费记录的盈利合计,即SUM((菜肴单价- 菜肴成本单价)×消费数量)。
(6)消费单明细表CList (消费单号Cid,序号Sid,菜肴编号Mid,菜肴名称Mname,消费数量Cqty,菜肴单价Mprice,菜肴成本单价Mcost,消费金额Cmoney) ,消费金额=消费数量×菜肴单价;消费数量为正数是正常点菜,消费数量为负数是退菜,消费数量为0是赠菜。
2.1 触发器设计2.1.1 为消费单明细表CList定义一个触发器,每插入(INSERT)一条消费单明细记录(消费单号,序号,菜肴编号,消费数量),自动根据菜肴编号从菜单信息表MList中读取菜肴名称Mname、菜肴单价Mprice、菜肴成本单价Mcost,然后计算其消费金额(=消费数量×菜肴单价)、以及消费单主表C的消费金额合计、盈利金额合计。
编写相应的插入语句(INSERT)和查询语句(SELECT)测试该触发器效果。
2.1.2 为消费单明细表CList定义一个触发器,每更新UPDATE一条消费单明细表记录,自动修改其消费金额、以及消费单主表C的消费金额合计、盈利金额合计。
编写相应的更新语句(UPDATE)和查询语句(SELECT)测试该触发器效果。
2.1.3 为消费单明细表CList定义一个触发器,每删除DELETE一条消费单明细表记录自动修改其消费单主表C的消费金额合计、盈利金额合计。
编写相应的删除语句(DELETE)和查询语句(SELECT)测试该触发器效果。
2.1.4 将【2.1.1】、【2.1.2】、【2.1.3】三个触发器禁用disable,重新编写一个触发器实现这三个触发器的全部功能。
编写相应的插入语句(INSERT)、更新语句(UPDATE)、删除语句(DELETE)和查询语句(SELECT)测试该触发器效果。
2.2 存储过程、自定义函数设计2.2.1设计一个自定义函数fGetDTSum,实现统计某年份给定餐台类别的成本金额合计的功能,输入参数是统计年份和餐台类别,返回数据是成本金额合计。
成本金额=消费数量×菜肴成本单价。
求年份的函数为EXTRACT(YEAR FROM 日期字段),本题:统计年份= EXTRACT(YEAR FROM EndTime),EndTime为结账时间字段。
2.2.2设计一个存储过程pGetKindSum,实现统计某年份给定菜肴类别的盈利金额合计的功能,输入参数是统计年份和菜肴类别,输出参数是盈利金额合计。
盈利金额=消费数量× (菜肴单价- 菜肴成本单价)。
2.2.3编写一段匿名PL/SQL程序块,调用函数fGetDTSum,输出2013年餐台类别名为“包间”的成本金额合计;调用存储过程pGetKindSum,输出2013年菜肴类别名为“鱼类”的盈利金额合计。
2.3 程序包设计2.3.1设计一个程序包,包名为pkSUM,包括并实现【2.2.1】和【2.2.2】的函数及存储过程功能,注意:先创建包头package,包头创建成功后,再创建包体package body。
2.3.2 设计一个匿名PL/SQL程序块,参照【2.2.3】调用【2.3.1】中程序包的函数和存储过程,输出2013年餐台类别名为“散台”的成本金额合计,输出2013年菜肴类别名为“蔬菜类”的盈利金额合计。
3.实验步骤(备注:如果用实验室微机,请从【3.2】开始做,登录用户DINER改为stu XX)3.1 创建表空间RESTAURANT,创建用户DINER3.1.2 用户SYSTEM登录Oracle3.1.3创建表空间RESTAURANT,大小10M。
CREATE TABLESPACE RESTAURANTDATAFILE'F:\RESTAURANT.ora'SIZE10MDEFAULT STORAGE(INITIAL10KNEXT50KMINEXTENTS1MAXEXTENTS99PCTINCREASE10)ONLINE;3.1.4 创建用户DINER,口令XXX,默认表空间RESTAURANT,给该用户授予角色权限CONNECT、RESOURCE。
CREATE USER DINER IDENTIFIED BY "wzl123" DEFAULT TABLESPACE RESTAURANT;GRANT CONNECT TO DINER;GRANT RESOURCE TO DINER;3.2 创建餐饮系统数据库的所有表,并向各表插入演示数据3.2.1启动PL/SQL Developer(或者启动SQL*PLUS、Enterprise Manager Console、浏览器模式的EM(企业管理器)等工具均可以),用户DINER登录Oracle。
3.2.2 创建实验内容中的餐饮系统数据库的所有表(菜肴类别表MK、菜单信息表MList、餐台类别表DK、餐台信息表Dinfo、消费单主表C、消费单明细表CList)。
create table MK(MKid number,MkName varchar2(64),constraint pk_MKid primary key(MKid));create table MList(Mid number,Mname varchar2(64),MKid number references MK(MKid),Mprice number(8,2),Mcost number(8,2),Mdate date,constraint pk_Mid primary key(Mid));create table DK(DKid number,DkName varchar2(64),constraint pk_DKid primary key(DKid));create table Dinfo(Did number,Dname varchar2(64),DKid number references DK(DKid),Dseats number,Ddate date,constraint pk_Did primary key(Did));create table C(Cid number,Did number references Dinfo(Did),StartTime date,EndTime date,Smoney number(8,2),SPsum number(8,2),constraint pk_Cid primary key(Cid));create table CList(Sid number,Cid number references C(Cid),Mid number references MList(Mid),Mname varchar2(64),Cqty number,Mprice number(8,2),Mcost number(8,2),Cmoney number(8,2),constraint pk_Sid primary key(Sid));3.2.3依次向菜肴类别表MK、菜单信息表MList、餐台类别表DK、餐台信息表Dinfo插入足够多的演示数据。
insert into MK values(1,'鱼类');insert into MK values(2,'蔬菜类');insert into MK values(3,'凉菜类');insert into MK values(4,'肉类');insert into MK values(5,'主食类');insert into MK values(6,'酒水');insert into MList values(1,'鲤鱼',1,50.00,30.00,sysdate); insert into MList values(2,'三文鱼',1,120.00,80.00,sysdate); insert into MList values(3,'白菜',2,15.00,5.00,sysdate); insert into MList values(4,'土豆',2,12.00,4.00,sysdate); insert into MList values(5,'油麦菜',2,12.00,5.00,sysdate); insert into MList values(6,'凉拌黄瓜',3,5.00,3.00,sysdate); insert into MList values(7,'鸡肉',4,30.00,10.00,sysdate); insert into MList values(8,'米饭',5,1.50,0.50,sysdate); insert into MList values(9,'二锅头',6,50.00,30.00,sysdate);insert into DK values(1,'包间');insert into DK values(2,'散台');insert into Dinfo values(1,'1号包间',1,20,sysdate);insert into Dinfo values(2,'2号包间',1,30,sysdate);insert into Dinfo values(3,'3号包间',1,50,sysdate);insert into Dinfo values(4,'1号散台',2,8,sysdate);insert into Dinfo values(5,'2号散台',2,8,sysdate);insert into Dinfo values(6,'3号散台',2,15,sysdate);insert into C values(1,2,sysdate,sysdate,275,150);insert into C values(2,2,sysdate,sysdate,155,80);insert into C values(3,1,sysdate,sysdate,566,302);insert into C values(4,2,sysdate,sysdate,89,53);insert into C values(5,1,sysdate,sysdate,798,435);insert into CList values(1,1,2,'三文鱼',1,120.00,80.00,120.00);insert into CList values(2,1,5,'油麦菜',1,12.00,5.00,12.00);insert into CList values(3,1,9,'二锅头',2,50.00,30.00,100.00);3.3 完成【实验内容】中的触发器、存储过程、函数和程序包等功能设计,将程序脚本保存到文本文件Source.sql中3.3.1 在PL/SQL Developer环境下,用户DINER登录Oracle3.3.2新建SQL窗口3.3.3 完成【2.1 触发器设计】(1)2.1.1CREATE OR REPLACE TRIGGER tri_CListBEFORE INSERT ON CList FOR EACH ROWDECLAREt_Smoney C.Smoney%type;t_SPsum C.SPsum%type;BEGIN--补全MlistSELECT Mname,Mprice,Mcost,:new.Cqty*MpriceINTO:new.Mname,:new.Mprice,:new.Mcost,:new.CmoneyFROM Mlist WHERE Mlist.Mid=:new.Mid;--计算Mlist的增加量SELECT NVL(SUM(Cqty*Mprice),0),NVL(SUM(Cqty*(Mprice-Mcost)),0)INTO v_Smoney,v_SPsum FROM Clist WHERE Clist.Cid=:new.Cid;--更新Cupdate C set Smoney=t_Smoney+:new.Cmoney,SPsum=t_SPsum+(:new.Cqty*(:new.Mprice-:new.Mcost)) where C.Cid=:new.Cid;END tri_CList;(2)2.1.2CREATE OR REPLACE TRIGGER tri_upCList BEFORE UPDATE ON CList FOR EACH ROWBEGINSELECT Mname,Mprice,Mcost INTO:new.Mname,:new.Mprice,:new.McostFROM Mlist WHERE Mlist.Mid=:new.Mid;:new.Cmoney:=NVL(:new.Cqty,:old.Cqty)*NVL(:new.Mprice,:old.Mprice);UPDATE C SET Smoney=Smoney-:old.Cmoney+:new.Cmoney,SPsum=SPsum-:old.Cqty*(:old.Mprice-:old.Mcost)+:new.Cqty*(:new.Mprice-:new.Mcost) WHERE C.Cid=:old.Cid;END tri_upCList;(3)2.1.3CREATE OR REPLACE TRIGGER tri_delCListBEFORE DELETE ON CList FOR EACH ROWBEGINUPDATE C SET C.Smoney=C.Smoney-:old.Cmoney,C.SPsum=C.SPsum-(:old.Cqty*(:old.Mprice-:old.Mcost))WHERE C.Cid=:old.Cid;END tri_delCList;(4)2.1.4CREATE OR REPLACE TRIGGER tri_allBEFORE INSERT OR UPDATE OR DELETEON CListFOR EACH ROWDECLAREt_Smoney C.Smoney%type;t_SPsum C.SPsum%type;BEGINIF INSERTING THENSelect Mname,Mprice,Mcost,:new.Cqty*Mpriceinto:new.Mname,:new.Mprice,:new.Mcost,:new.Cmoneyfrom Mlistwhere Mlist.Mid=:new.Mid;Select nvl(sum(Cqty*Mprice),0),nvl(sum(Cqty*(Mprice-Mcost)),0)into t_Smoney,t_SPsumfrom Clistwhere Clist.Cid=:new.Cid;update Cset Smoney=t_Smoney+:new.Cmoney,SPsum=t_SPsum+(:new.Cqty*(:new.Mprice-:new.Mcost)) where C.Cid=:new.Cid;ELSIF UPDATING THENselect Mname,Mprice,Mcostinto:new.Mname,:new.Mprice,:new.Mcostfrom Mlistwhere Mlist.Mid=:new.Mid;:new.Cmoney:=nvl(:new.Cqty,:old.Cqty)*nvl(:new.Mprice,:old.Mprice);Update C set Smoney=Smoney-:old.Cmoney+:new.Cmoney,SPsum=SPsum-:old.Cqty*(:old.Mprice-:old.Mcost)+:new.Cqty*(:new.Mprice-:new.Mcost) where C.Cid=:old.Cid;ELSEUPDATE C SETC.Smoney=C.Smoney-:old.Cmoney,C.SPsum=C.SPsum-(:old.Cqty*(:old.Mprice-:old.Mcost));END IF;END tri_all;3.3.4 完成【2.2 存储过程、自定义函数设计】(1)2.2.1CREATE OR REPLACE FUNCTION fGetDTSum(Cyear char,Ctable dk.dkname%type)RETURN C.spsum%TYPEAScons C.spsum%TYPE;BEGINselect nvl(sum(spsum),0)into cons from Cwhere did in(select did from dinfo where dkid in(select dkid from dk where dkname=Ctable))and(to_char(endtime,'YYYY')=Cyear);RETURN cons;EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data is invalid!');END fGetDTSum;(2)2.2.2CREATE OR REPLACE PROCEDURE pGetKindSum(Cyear char,Cname char,cons out clist.mcost%TYPE)ASBEGINselect nvl(sum(mprice-mcost),0)into cons from clist where mid in(select mid from mlist where mkid in(select mkid from mk where mkname=Cname))andcid in(select cid from C where to_char(endtime,'YYYY')=Cyear); EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data doesn’’t exists!'); END pGetKindSum;(3)2.2.3DECLAREcons1 C.spsum%TYPE;cons2 clist.mcost%TYPE;BEGINcons1:=fGetDTSum('2013','包间');pGetKindSum('2013','鱼类',cons2);DBMS_OUTPUT.PUT_LINE('cons1 '||cons1||'cons2 '||cons2||''); END;3.3.5完成【2.3 程序包设计】(1)2.3.1CREATE OR REPLACE PACKAGE pkSUMASFUNCTION fGetDTSum(Cyear char,Ctable dk.dkname%type)RETURN C.spsum%TYPE;PROCEDURE pGetKindSum(Cyear char,Cname char,cons out clist.mcost%TYPE);END pkSUM;CREATE OR REPLACE PACKAGE BODY pkSUMASCREATE OR REPLACE FUNCTION fGetDTSum(Cyear char,Ctable dk.dkname%type)RETURN C.spsum%TYPEAScons C.spsum%TYPE;BEGINselect nvl(sum(spsum),0)into cons from Cwhere did in(select did from dinfo where dkid in(select dkid from dk where dkname=Ctable))and(to_char(endtime,'YYYY')=Cyear);RETURN cons;EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data is invalid!');END fGetDTSum;CREATE OR REPLACE PROCEDURE pGetKindSum(Cyear char,Cname char,cons out clist.mcost%TYPE)ASBEGINselect nvl(sum(mprice-mcost),0)into cons from clistwhere mid in(select mid from mlist where mkid in(select mkid from mk where mkname=Cname))andcid in(select cid from C where to_char(endtime,'YYYY')=Cyear);EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data doesn’’t exists!');END pGetKindSum;END pkSUM;CREATE OR REPLACE PACKAGE BODY pkSUMASCREATE OR REPLACE FUNCTION fGetDTSum(Cyear char,Ctable dk.dkname%type)RETURN C.spsum%TYPEAScons C.spsum%TYPE;BEGINselect nvl(sum(spsum),0)into cons from Cwhere did in(select did from dinfo where dkid in(select dkid from dk where dkname=Ctable))and(to_char(endtime,'YYYY')=Cyear);RETURN cons;EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data is invalid!');END fGetDTSum;CREATE OR REPLACE PROCEDURE pGetKindSum(Cyear char,Cname char,cons out clist.mcost%TYPE)ASBEGINselect nvl(sum(mprice-mcost),0)into cons from clistwhere mid in(select mid from mlist where mkid in(select mkid from mk where mkname=Cname))andcid in(select cid from C where to_char(endtime,'YYYY')=Cyear);EXCEPTIONWHEN NO_DATA_FOUND THENDBMS_OUTPUT.PUT_LINE('The data doesn’’t exists!');END pGetKindSum;END pkSUM;(2)2.3.2DECLAREcons1 C.spsum%TYPE;cons2 clist.mcost%TYPE;BEGINcons1:=pkSUM.fGetDTSum1('2013','散台');pkSUM.pGetKindSum1('2013','蔬菜类',cons2);DBMS_OUTPUT.PUT_LINE('cons1:'||cons1||' cons2:'||cons2||'');END;4.实验总结这次实验让我学会了许多东西,比如PLSQL Developer的使用,高级PL/SQL 程序的编写,其中包括触发器,储存过程,自定义函数,匿名函数,程序包的设计与编写。