Oracle存储过程、包详解
作者:IT邦德中国DBA联盟(ACDU)成员,目前从事DBA及程序编程(Web\java\Python)工作,主要服务于生产制造现拥有 Oracle 11gOCP/OCM、Mysql、Oceanbase(OBCA)认证分布式TBase\TDSQL数据库、国产达梦数据库以及红帽子认证从业8年DBA工作,在数据库领域有丰富的经验B站主播Oracle、Mysql、PG实战课程,请搜索:jeames007
·
作者:IT邦德
中国DBA联盟(ACDU)成员,目前从事DBA及程序编程
(Web\java\Python)工作,主要服务于生产制造
现拥有 Oracle 11g OCP/OCM、
Mysql、Oceanbase(OBCA)认证
分布式TBase\TDSQL数据库、国产达梦数据库以及红帽子认证
从业8年DBA工作,在数据库领域有丰富的经验
B站主播Oracle、Mysql、PG实战课程,请搜索:jeames007
擅长Oracle数据库运维开发,备份恢复,安装迁移,性能优化、故障应急处理等。
前言
本文总结了PL\SQL存储过程及包的使用,大家多点赞关注!1.pl/sql块介绍
1.1、只包括执行部分的pl/sql块
SQL>set serveroutput on --打开输出选项
begin /*执行部分——要执行的pl/sql语句和sql语句*/
dbms_output.put_line('hello');
end;
/
/*dbms_output是oracle所提供的包(类似java的开发包),该包包含一些过程,put_line就是dbms_output包的一个过程*/
包含定义部分和执行部分的pl/sql块
1.2、包含定义部分和执行部分的pl/sql块
SQL>declare
v_ename varchar2(5); --定义字符串变量
begin
select ename into v_ename from emp where empno=&aa;
dbms_output.put_line('雇员名:'||v_ename);
end;
/
1.3、 包含定义部分,执行部分和例外处理部分的pl/sql块
SQL>declare
--定义变量
v_ename varchar2(5);
v_sal number(7,2);
begin
--执行部分
select ename,sal into v_ename,v_sal from emp where empno=&aa;
--在控制台显示用户名
dbms_output.put_line('用户名是:'||v_ename||' 工资:'||v_sal);
--异常处理
exception
when no_data_found then
dbms_output.put_line('朋友,你的编号输入有误!');
end;
/
2.pl/sql分类
2.1、过程
SQL>create procedure sp_pro(spName varchar2, newSal number) is
begin
--执行部分,根据用户名去修改工资
update emp set sal=newSal where ename=spName;
end;
/
SQL>exec sp_pro1('SCOTT',4556); --调用
2.2、函数
--输入雇员的姓名,返回该雇员的年薪
SQL>create function annual_incomec(name varchar2)
return number is
annual_salazy number(7,2);
begin
--执行部分
select sal*12+nvl(comm, 0) into annual_salazy from emp where ename=name;
return annual_salazy;
end;
/
--在sqlplus中调用函数
SQL>var income number
call annual_incomec('SCOTT') into: income;
print income
2.3、 包
--包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成。
实例1:
--创建一个包sp_package
--声明该包有一个过程update_sal
--声明该包有一个函数annual_income
SQL>create package sp_package is
procedure update_sal(name varchar2, newsal number);
function annual_income(name varchar2) return number;
end;
/
实例2:
--给包sp_package实现包体
SQL>create or replace package body sp_package is
procedure update_sal(name varchar2, newsal number)
is
begin
update emp set sal = newsal where ename = name;
end;
function annual_income(name varchar2) return number is
annual_salary number;
begin
select sal * 12 + nvl(comm, 0) into annual_salary from emp
where ename = name;
return annual_salary;
end;
end;
/
如何调用包的过程或是函数
SQL> call sp_package.update_sal('SCOTT', 1500);
2.4、触发器
常用的触发事件包括insert,update,delete语句,而触发操作实际就是一个pl/sql块。可以使用create trigger来建立触发器。
3.定义并使用变量,复合类型
3.1、标量定义的案例
定义一个变长字符串
v_ename varchar2(10);
定义一个小数,范围 -9999.99~9999.99
v_sal number(6,2);
定义一个小数并给一个初始值为5.4 :=是pl/sql的赋值号
v_sal2 number(6,2):=5.4;
定义一个日期类型的数据
v_hiredate date;
定义一个布尔变量,不能为空,初始值为false
v_valid boolean not null default false;
案例1:
SQL> declare
c_tax_rate number(3,2):=0.03;
--用户名
v_ename varchar2(5);
v_sal number(7,2);
v_tax_sal number(7,2);
begin
--执行
select ename,sal into v_ename,v_sal from emp where empno=&no;
--计算所得税
v_tax_sal := v_sal*c_tax_rate;
--输出
dbms_output.put_line('姓名是:'||v_ename||'工资:'||v_sal||' 交税:'||v_tax_sal);
end;
/
输出的结果是:
姓名是:SCOTT工资:2900 交税:87
PL/SQL procedure successfully completed
案例2:
标量(scalar)——使用%type类型
比如上例的v_ename,这样定义: v_ename emp.ename%type;
3.2、复合变量(composite)
用于存放多个值的变量。主要包括这几种:
pl/sql记录
pl/sql表
嵌套表
varray
3.2.1、pl/sql记录
类似于高级语言中的结构体,需要注意的是,当引用pl/sql记录成员时,必须要加记录变量作为前缀(记录变量.记录成员)如下:
SQL>declare
--定义一个pl/sql记录类型emp_record_type,类型包含3个数据name,salary,title。说白了,就是一个类型可以存放3个数据,主要是为了好管理
type emp_record_type is record(
name emp.ename%type,
salary emp.sal%type,
title emp.job%type);
--定义了一个sp_record变量,这个变量的类型是emp_record_type
sp_record emp_record_type;
begin
select ename, sal, job into sp_record from emp where empno = 7788;
dbms_output.put_line ('员工名:' || sp_record.name);
end;
/
3.2.2、pl/sql表
相当于高级语言中的数组,但是需要注意的是在高级语言中数组的下标不能为负数,而pl/sql是可以为负数的,并且表元素的下标没有限制。实例如下:
SQL>declare
--定义了一个pl/sql表类型sp_table_type,该类型是用于存放emp.ename%type
--index by binary_integer 表示下标是整数
type sp_table_type is table of emp.ename%type
index by binary_integer;
--定义了一个sp_table变量,这个变量的类型是sp_table_type
sp_table sp_table_type;
begin
select ename into sp_table(-1) from emp where empno = 7788;
dbms_output.put_line('员工名:' || sp_table(-1));
end;
/
说明:
sp_table_type 是pl/sql表类型
emp.ename%type 指定了表的元素的类型和长度
sp_table 为pl/sql表变量
sp_table(0) 则表示下标为0的元素
注意:如果把select ename into sp_table(-1) from emp where empno = 7788;变成select ename into sp_table(-1) from emp;则运行时会出现错误,错误如下:
ORA-01422:实际返回的行数超出请求的行数
解决方法是:使用参照变量
如果觉得文章对你有帮助,点赞、收藏、关注、评论,一键四连支持
您的批评指正是我写作的最大动力!
❤️ 技术交流可以 关注公众号:IT邦德 ❤️

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)