实训6:PL/SQL高级编程

实验目的

1、掌握PL/SQL的数据结构和编程结构,掌握应用PL/SQL编写简单程序的方法
2、理解存储过程的概念,掌握编写存储过程的方法
3、理解函数的概念,掌握编写存储过程的方法

实训内容

 一、PL/SQL编程基础

1、pl/sql的组成

声明块(DECLARE)、执行块(BEGIN和END包裹)、异常处理块(EXCEPTION)
 

2、编制代码实现1+2+...+100的计算

----自定义函数,如何将pl/sql中函数的改变后的参数带回原函数:用“in out”
create or replace procedure swap(startN in out int , endN in out int)
as
    temp int;
begin
    temp:=startN;
    startN:=endN;
    endN :=temp;
end;
DECLARE 
    -- 声明块
    startNum int;
	endNum int;
	i int;
    sumNum int;

BEGIN    
    -- 执行块
	startNum :=1;
    endNum :=100;

    if startNum > endNum then
        swap(startNum, endNum);
    end if;

    sumNum :=0;
    i := startNum;
    while i<=endNum loop
		sumNum:=sumNum+i;
		i:=i+1;
	end loop;
	dbms_output.put_line('结果是:'||sumNum);
    
    EXCEPTION
    -- 异常处理块
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE('An error occurred');

END;

二、存储过程编程

1、存储过程的概念

 procedure 存储过程,存储在数据库中的不带返回值的命名PL/sql程序块,(可以反复使用复杂操作,并提高执行效率)

2、存储过程的语法

create or replace procedure procedureName(parm parmType) 
as
	local varible defination
begin
	procedure body;
end;

 3、编写代码

3.1、求1+2+...+100的结果并显示的存储过程
create or replace procedure sp_calcSum 
as
    startNum int;
    endNum int;
    i int;
    sumResult int;
    
begin
	startNum := 1;
    endNum := 100;

    i:= startNum;
    sumResult:= 0;
    WHILE i <=endNum LOOP
        sumResult:=i+sumResult;
        i:=i+1;
    END LOOP;
    dbms_output.put_line('result is ' ||  sumResult);
end;

运行结果如下:

3.2、求1+2+...+n的带参数的存储过程
create or replace procedure sp_calcSum(Num int) 
as
    startNum int;
    endNum int;
    i int;
    sumResult int;
    
begin
	startNum := 1;
    endNum := Num;

    i:= startNum;
    sumResult:= 0;
    WHILE i <=endNum LOOP
        sumResult:=i+sumResult;
        i:=i+1;
    END LOOP;
    dbms_output.put_line('result is ' ||  sumResult);
end;

当Num=6时, 运行结果如下:

三、函数编程

1、函数的概念

function函数,存储在数据库中的带返回值的命名pl/sql程序块

2、函数的语法

create or replace function functionName(parm parmType) return resultType
as
	local varible defination
begin
	function body
	return result;
end;

 3、编写代码

3.1、求1+2+...+100的函数
CREATE OR REPLACE function f_calcSum RETURN int
as
    startNum int;
    endNum int;
    i int;
    sumResult int;
    
begin
	startNum := 1;
    endNum := 100;

    i:= startNum;
    sumResult:= 0;
    WHILE i <=endNum LOOP
        sumResult:=i+sumResult;
        i:=i+1;
    END LOOP;
    RETURN sumResult;
END;

运行结果如下:

3.2、求1+2+...+n的函数
create or replace function f_calcSum(pEndNumber int) return int
as
    startNum int;
    endNum int;
    i int;
    sumResult int;
    
begin
	startNum := 1;
    endNum := pEndNumber;

    i:= startNum;
    sumResult:= 0;
    WHILE i <=endNum LOOP
        sumResult:=i+sumResult;
        i:=i+1;
    END LOOP;
    RETURN sumResult;
END;

当pEndNumber=5时,运行结果如下:

四、存储过程与函数的应用

1、编写代码

1.0、前置条件

你已经配备了EMP员工表与DEPT部门表,表内内容不赘述,具体可看实训2。

1.1、问题一

将指定部门号的所有员工薪水增加指定值的存储过程,并调用此存储过程将30号部门的薪水增加1000

Part 1. 编写存储过程 sp_AlterSalByDeptno(pSalDelta,pDeptno)

CREATE OR REPLACE PROCEDURE sp_AlterSalByDeptno(pSalDelta NUMBER, pDeptno NUMBER)
AS
BEGIN
    UPDATE EMP
    SET sal = sal + pSalDelta
    WHERE deptno = pDeptno;
    
    COMMIT;
    
    DBMS_OUTPUT.PUT_LINE('Successfully updated salaries for department ' || pDeptno);

	EXCEPTION
			WHEN OTHERS THEN
				DBMS_OUTPUT.PUT_LINE('Error updating salaries: ' || SQLERRM);
			ROLLBACK;
END;

30号部门当前的薪水sal为:

Part 2.调用存储过程将30号部门的薪水增加1000元

execute sp_AlterSalByDeptno(1000,30);

30号部门此时的薪水sal为:

Part 3.与使用update语句进行对比 (内容来自网络)

使用存储过程的优点:

  1. 可以将复杂的业务逻辑封装在存储过程中,提高了代码的模块化和可维护性。
  2. 可以通过存储过程的参数来动态地传递值,增强了存储过程的灵活性和通用性。
  3. 可以在存储过程中实现错误处理机制,提高了程序的健壮性和稳定性。

使用存储过程的缺点:

  1. 存储过程的编写和调试相对复杂,需要一定的数据库开发经验。
  2. 存储过程依赖于数据库平台,不够具有通用性,可能会限制系统的可移植性。
  3. 存储过程的执行效率可能不如直接执行 SQL 语句,因为存储过程的执行涉及到编译和解释的过程。
1.2、问题二 

求指定部门号的所有员工平均薪水的函数,并调用此函数计算30号部门的平均薪水 

Part 1.编写函数 f_GetAvgSalByDeptno(pDeptno)

CREATE OR REPLACE FUNCTION f_GetAvgSalByDeptno(pDeptno NUMBER) RETURN NUMBER
AS
    v_avg_sal NUMBER;

BEGIN
    -- 使用 AVG 函数计算指定部门号的所有员工平均薪水
    SELECT AVG(sal) INTO v_avg_sal
    FROM emp
    WHERE deptno = pDeptno;
    
    RETURN v_avg_sal;

EXCEPTION
    WHEN NO_DATA_FOUND THEN
        RETURN NULL; -- 如果找不到数据,则返回 NULL
END;

Part 2.调用函数求出30号部门的平均薪水并显示temp:=f_GetAvgSalByDeptno(30)

DECLARE
    tempSal NUMBER;
BEGIN
    -- 调用函数获取30号部门的平均薪水
    tempSal:= f_GetAvgSalByDeptno(30);
    
    -- 输出结果
    DBMS_OUTPUT.PUT_LINE('Average salary for department 30: ' ||tempSal);
END;

运行结果如下:

Part 3.与使用select语句进行对比 (内容来自网络)

使用函数的优点:

  1. 可以将复杂的业务逻辑封装在函数中,提高了代码的模块化和可维护性。
  2. 可以通过函数的参数来动态地传递值,增强了函数的灵活性和通用性。
  3. 可以在函数中实现错误处理机制,提高了程序的健壮性和稳定性。

使用函数的缺点:

  1. 函数的编写和调试相对复杂,需要一定的数据库开发经验。
  2. 函数依赖于数据库平台,不够具有通用性,可能会限制系统的可移植性。
  3. 函数的执行效率可能不如直接执行 SQL 语句,因为函数的执行涉及到编译和解释的过程。

2、结论

需要频繁重复的数据库操作通常会编制专门的存储过程或函数

存储过程应用: 先创建存储过程(编写sql语句,将编写的代码编译后保存在数据库中,同时存储了编写的plsql语句和对应的编译后的机器操作指令),再使用存储过程(直接调用机器操作指令)

sql语句:update emp set sal=sal+1000  where deptno=30; (先检查sql是否正确,再转换成机器操作指令,最后执行机器操作)

对比:!!!看“---”后的字
 

while deptno in(10,20,30) loop

	execute alterSalBydeptno(delta,target); ---1  每次只需直接执行
	
    update emp set sal=sal+delta where deptno=target;  ---2  每次执行都要检查、转换、执行
	DeptnoMoveNext();

end loop

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
第一章 集合 1.1 索引表 1.1.1 定义索引表 1.1.2 将条目插入到索引表中 1.1.3 对索引表中进行操作 1.1.4 索引表中的函数 1.2 嵌套表 1.2.1 初始化嵌套表 1.2.2 扩展嵌套表 1.2.3 删除嵌套表中的条目 1.3 变长数组 1.3.1 定义变长数组 1.3.2 扩展变长数组 1.4 批绑定 1.5 集合的异常处理 第二章 触发器 2.1 触发器的创建 2.2 触发器的管理 2.3 触发器的新功能 2.4 替代触发器 2.5 触发器的局限性 第三章 对象 3.1 对象的定义 3.2 对象的存贮和检索 第四章 调试 4.1 编写 DEBUG 程序包(例程) 4.2 调用函数 第五章 大对象类型 5.1 大对象数据类型 5.2 在Oracle8i 数据库中使用外部文件: 5.3 DBMS_LOB 包 5.3.1 函数说明 5.3.2 应用举例 5.3.3 内部 LOB 的函数和过程5.3.4 内部 LOB 的函数和过程的应用举例 5.3.5 临时 LOB 第六章 管理事务和锁定 6.1 事务 6.2 锁定 第七章 动态 SQL 7.1 DBMS_SQL 程序包 7.2 本机动态SQL 7.2.1 执行 DDL 语句 7.2.2 使用绑定变量 7.2.3 执行 PL/SQL 块 第八章 显示数据 8.1 DBMS_OUTPUT 程序包 8.1.1 开启屏幕显示 8.1.2 关闭屏幕显示 8.1.3 其他函数 8.1.4 引发的异常 8.2 UTL_FILE 程序包 8.2.1 概述 8.2.2 函数描述 8.2.3 例程 8.3 TEXT_IO 程序包 第九章 管理数据作业 9.1 DBMS_JOB 包 9.2 使用后台进程 9.3 执行作业 9.3.1 使用SUBMIT 将作业提交给作业队列 9.3.2 使用RUN 立即执行作业 9.3.3 作业环境 9.4 查看作业 9.4.1 DBA_JOBS 视图的结构 9.4.2 DBA_JOBS_RUNNING 视图的结构 9.5 管理作业 9.5.1 删除作业 9.5.2 修改作业 9.5.3 导入和导出作业 9.5.4 处理损坏的作业 9.5.5 例程 第十章 过程通信 10.1 报警(DBMS_ALERT 程序包) 10.1.1 建立报警的次序 10.1.2 函数应用和说明 10.1.3 应用举例 10.2 DBMS_PIPE 程序包 10.2.1 公有管道和私有管道 10.2.2 使用管道 10.2.3 DBMS_PIPE 包的函数 10.2.4 例程 10.3 DBMS_ALERT 与 DBMS_PIPE 的比较 第十一章 PL/SQL 和 JAVA 11.1 Oracle JAVA 11.2 装载、应用、删除JAVA
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值