文章目录
一、基础介绍
- 存储过程和函数也是数据库对象,是存储在数据库中的被命名的PLSQL块,供所有用户程序调用完成特定功能的子程序。
- 存储过程类似java中的void方法,主要用途是功能的处理,存储该函数类似非void方法,需要return返回值。
二、存储过程
(一) 创建和调用
语法
CREATE [OR REPLACE] PROCEDURE 过程名
[(参数名1 IN|OUT|IN OUT 参数值类型 [DEFAULT 默认值]),
(参数名2 IN|OUT|IN OUT 参数值类型[DEFAULT 默认值])...]
AS|IS
[变量名 变量类型[:=初始值]; --声明变量部分 ]
BEGIN
执行部分;
[EXCEPTION
异常错误处理部分;]
END;
1.无参的存储过程
1)创建
--创建存储过程(无参)
CREATE OR REPLACE
PROCEDURE first_proc2 is--
BEGIN
DBMS_OUTPUT.PUT_LINE('我是过程2');--打印内容
DBMS_OUTPUT.PUT_LINE('hello everyone!');
END;
2)调用
BEGIN
first_proc2;
end;
2.带输入参数的存储过程in
1)创建
create or replace procedure proc_inparams
(v_empno in EMPNEW.EMPNO%TYPE)--名称是v_empno的In类型的参数,TYPE与emp_1表的empno字段相同
IS
begin
--根据员工号删除指定员工信息
delete from EMPNEW where empno=v_empno;--一般不用在程序中commit和rollback
--判断是否成功
if SQL%NOTFOUND then
-- -20000~20999之间
RAISE_APPLICATION_ERROR(-20008,'指定删除的员工不存在');--内置的存储过程,用于在子程序中指定错误的自定义信息,错误号和错误提示内容可以自定义
ELSE
DBMS_OUTPUT.PUT_LINE('删除成功');
END IF;
end;
2)调用
BEGIN
PROC_INPARAMS(1234);--调用时传参
end;
DECLARE
dpn number:=1234;
BEGIN
PROC_INPARAMS(dpn);
end;
3.带输出过程的存储过程out
1)创建
create or replace procedure proc_outparams
(v_deptno in number,v_avgsal out number,v_cnt out number)
AS
BEGIN
select avg(sal),count(*) into v_avgsal,v_cnt --参数变量赋值into
from EMP
where deptno=v_deptno;
EXCEPTION
when NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('无此部门');
when others THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;
2)调用
DECLARE
v_avgsalary number;--声明两个变量用于接收out参数
v_count number;
BEGIN
PROC_OUTPARAMS(10,v_avgsalary,v_count);--位置传值,声明的变量按照顺序对应接收out参数
DBMS_OUTPUT.put_line('平均工资:'||v_avgsalary);
DBMS_OUTPUT.put_line('总人数:'||v_count);
end;
4.带输入输出过程的存储过程in out
1)创建
create or replace procedure proc_inoutparams
(v_num1 in out number,v_num2 in out number)
as
v_temp number:=0;--声明一个叫v_temp的变量,type是NUMBER,赋值0
BEGIN
--交换两个数
v_temp:=v_num1;
v_num1:=v_num2;
v_num2:=v_temp;
end;
2)调用
DECLARE
v_n1 number:=5;--声明两个变量用于接收参数
v_n2 number:=8;
BEGIN
PROC_INOUTPARAMS(v_n1,v_n2);--声明的变量按照顺序对应接收in out参数
DBMS_OUTPUT.put_line('v_n1:'||v_n1);
DBMS_OUTPUT.put_line('v_n2:'||v_n2);
end;
(二) 删除
drop procedure "first_proc";--过程名区分是否有引号
三、存储函数
(一) 创建和调用
语法
CREATE [OR REPLACE] FUNCTION 函数名
[(参数名1 IN|OUT|IN OUT 参数值类型 [DEFAULT 默认值]),
(参数名2 IN|OUT|IN OUT 参数值类型 [DEFAULT 默认值])...]
RETURN 返回值类型--比过程多的部分
AS|IS
[变量名 变量类型[:=初始值]; --声明变量部分 ]
BEGIN
执行部分;
[EXCEPTION
异常错误处理部分;]
END;
1.无参的存储函数
1)创建
CREATE OR REPLACE function "first_func2"
return VARCHAR2
iS
BEGIN
DBMS_OUTPUT.PUT_LINE('我是函数2');
return 'hello,everyone';--对应之前的类型
END;
2)调用
BEGIN
dbms_output.put_line(first_func2);
end;
2.带输入参数的存储函数in
1)创建
create or replace function func_inparams
(v_deptno in number)
return NUMBER
is
v_sumsal number;--声明变量
BEGIN
--根据部门编号返回部门总工资
select sum(sal) into v_sumsal from emp where DEPTNO=v_deptno;--变量赋值
return v_sumsal;--返回变量
EXCEPTION
when no_data_found THEN
dbms_output.put_line('无此部门');
when others THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
2)调用
BEGIN
dbms_output.put_line('部门工资总和:'||FUNC_INPARAMS(10));
end;
3.带输出过程的存储函数out
1)创建
create or replace function func_outparams
(v_empno in EMP.EMPNO%type, v_name out EMP.ENAME%type,v_sal out EMP.SAL%type )
return number
AS
v_yasal number;
BEGIN
--根据员工号输出员工姓名和工资,并返回员工的年收入
select ename,sal,(sal+nvl(comm,0))*12 into v_name,v_sal,v_yasal
from EMP
where empno=v_empno;
return v_yasal;
EXCEPTION
when no_data_found THEN
dbms_output.put_line('无此员工');
when others THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
2)调用
DECLARE
v_name EMP.ENAME%type;--声明两个变量用于接收out参数
v_sal EMP.SAL%type;
v_yasal number;
BEGIN
v_yasal:=FUNC_OUTPARAMS(7369,v_name,v_sal);
dbms_output.put_line('姓名'||v_name||'的工资是'||v_sal||',年总收入是:'||v_yasal);
end;
4.带输入输出过程的存储函数in out
1)创建
create or replace function func_inoutparams
(n1 in out number,n2 in out number)
return NUMBER
AS
BEGIN
n1:=n1*n1;
n2:=n2*n2;
return n1+n2;
end;
2)调用
DECLARE
v_n1 number :=5;
v_n2 number :=8;
BEGIN
dbms_output.put_line(v_n1||'和'||v_n2||'的和是:'||FUNC_INOUTPARAMS(v_n1, v_n2));--此时v_n1和v_n2已经参与函数计算
end;
(二) 删除
drop function "first_func";
四、使用DEFAULT默认值
1.单个参数
--------------------------------求部门的年收入----------------------
--创建
CREATE OR REPLACE
function func_defa
(v_deptno in number DEFAULT 10)
return NUMBER
AS
v_deptysal number;
BEGIN
select sum(sal+nvl(comm,0))*12 into v_deptysal
from emp where deptno=v_deptno;
return v_deptysal;
EXCEPTION
when NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('没有此部门');
when others THEN
DBMS_OUTPUT.put_line(SQLERRM);
end;
--调用
BEGIN
dbms_output.put_line('部门年收入总和:'||FUNC_DEFA);--使用默认值,不用传参
dbms_output.put_line('部门年收入总和:'||FUNC_DEFA(20));--不用默认值,需要传参
end;
2.多个参数
---------------------------求部门的年收入---------------------
--创建
CREATE OR REPLACE
function func_defa2
(v_deptno in number DEFAULT 10,v_test in number)
return NUMBER
AS
v_deptysal number;
BEGIN
select sum(sal+nvl(comm,0))*12 into v_deptysal
from emp where deptno=v_deptno;
DBMS_OUTPUT.put_line('测试:'||v_test);
return v_deptysal;
EXCEPTION
when NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('没有此部门');
when others THEN
DBMS_OUTPUT.put_line(SQLERRM);
end;
--调用
BEGIN
--dbms_output.put_line('部门年收入总和:'||FUNC_DEFA2(,888));--第一个参数省略时,位置传值,报错,不能这样传
dbms_output.put_line('部门年收入总和:'||FUNC_DEFA2(v_test=>888));--名称传值,关联符号=>
end;
五、比较
1.关键字
创建过程:procedure
创建函数:function
2.调用方式
存储过程使用独立的调用语句
begin
proc1
end;
存储函数以表达式方式调用
declare
v_result NUMBER;
begin
v_result:=func1;
end;
4.return返回值
存储函数通过return语句返回函数值,存储过程则没有
5.用途
存储过程的目的是完成一系列的数据处理;存储函数的目的是获得函数返回值。
6.参数
过程和函数都可以有一个或多个out输出函数。
存储过程没有return语句,但是可以通过out参数来实现返回值。
一般原则,如果只有一个返回值,用存储函数处理