过程与函数(另外还有包与触发器)是命名的PL/SQL块(也是用户的方案对象),被编译后存储在数据库中,以备执行。所以,其它PL/SQL块能够按名称来使用他们。因此,能够将商业逻辑、企业规则写成函数或过程保存到数据库中,以便共享。数据库
过程和函数统称为PL/SQL子程序,他们是被命名的PL/SQL块,均存储在数据库中,并经过输入、输出参数或输入/输出参数与其调用者交换信息。过程和函数的惟一区别是函数总向调用者返回数据,而过程则不返回数据。在本节中,主要介绍:express
1. 建立存储过程和函数。
2. 正确使用系统级的异常处理和用户定义的异常处理。
3. 创建和管理存储过程和函数。安全
CREATE [OR REPLACE] FUNCTION function_name
(arg1 [ { IN | OUT | IN OUT }] type1 [DEFAULT value1],
[arg2 [ { IN | OUT | IN OUT }] type2 [DEFAULT value1]],
......
[argn [ { IN | OUT | IN OUT }] typen [DEFAULT valuen]])
[ AUTHID DEFINER | CURRENT_USER ]
RETURN return_type
IS | AS
<类型.变量的声明部分>
BEGIN
执行部分
RETURN expression
EXCEPTION
异常处理部分
END function_name;
l IN,OUT,IN OUT是形参的模式。若省略,则为IN模式。IN模式的形参只能将实参传递给形参,进入函数内部,但只能读不能写,函数返回时实参的值不变。OUT模式的形参会忽略调用时的实参值(或说该形参的初始值老是NULL),但在函数内部能够被读或写,函数返回时形参的值会赋予给实参。IN OUT具备前两种模式的特性,即调用时,实参的值老是传递给形参,结束时,形参的值传递给实参。调用时,对于IN模式的实参能够是常量或变量,但对于OUT和IN OUT模式的实参必须是变量。ide
l 通常,只有在确认function_name函数是新函数或是要更新的函数时,才使用OR REPALCE关键字,不然容易删除有用的函数。
例1. 获取某部门的工资总和:
--获取某部门的工资总和
SQL> create or replace
2 function f_get_salary(
3 Dept_no NUMBER,
4 Emp_count OUT NUMBER)
5 RETURN NUMBER
6 is
7 V_sum NUMBER;
8 BEGIN
9 SELECT SUM(SALARY), count(*) INTO V_sum, emp_count
10 FROM EMPLOYEES WHERE DEPARTMENT_ID=dept_no;
11 RETURN v_sum;
12 EXCEPTION
13 WHEN NO_DATA_FOUND THEN
14 DBMS_OUTPUT.PUT_LINE('你须要的数据不存在!');
15 WHEN OTHERS THEN
16 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
17 END f_get_salary;
18 /
Function created.模块化
函数声明时所定义的参数称为形式参数,应用程序调用时为函数传递的参数称为实际参数。应用程序在调用函数时,可使用如下三种方法向函数传递参数:函数
第一种参数传递格式:位置表示法。工具
即在调用时按形参的排列顺序,依次写出实参的名称,而将形参与实参关联起来进行传递。用这种方法进行调用,形参与实参的名称是相互独立,没有关系,强调次序才是重要的。性能
格式为:开发工具
argument_value1[,argument_value2 …]
第二种参数传递格式:名称表示法。测试
即在调用时按形参的名称与实参的名称,写出实参对应的形参,而将形参与实参关联起来进行传递。这种方法,形参与实参的名称是相互独立的,没有关系,名称的对应关系才是最重要的,次序并不重要。
格式为:
argument => parameter [,…]
其中:argument 为形式参数,它必须与函数定义时所声明的形式参数名称相同parameter 为实际参数。
在这种格式中,形势参数与实际参数成对出现,相互间关系惟一肯定,因此参数的顺序能够任意排列。
第三种参数传递格式:组合传递。
即在调用一个函数时,同时使用位置表示法和名称表示法为函数传递参数。采用这种参数传递方法时,使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说,不管函数具备多少个参数,只要其中有一个参数使用名称表示法,其后全部的参数都必须使用名称表示法。
SQL> DECLARE
2 V_num NUMBER;
3 V_sum NUMBER;
4 BEGIN
5 V_sum :=f_get_salary(emp_count => v_num, dept_no => 10);
6 DBMS_OUTPUT.PUT_LINE('10号部门工资总和:'||v_sum||',人数:'||v_num);
7 end;
8 /
10号部门工资总和:4400,人数:1
PL/SQL procedure successfully completed.
SQL> var V_sum NUMBER;
SQL> var V_num NUMBER;
SQL> exec :V_sum:=f_get_salary(:dept_no,:V_num);
PL/SQL procedure successfully completed.
SQL> print :V_sum :V_num
V_SUM
4400 V_NUM
1 SQL> select :V_sum ,:V_num from dual; :V_SUM :V_NUM
4400 1 SQL> run
1 begin
2 DBMS_OUTPUT.PUT_LINE('10号部门工资总和:'||:v_sum||',人数:'||:v_num);
3* end;
10号部门工资总和:4400,人数:1
SQL> DECLARE
2 V_num NUMBER;
3 V_sum NUMBER;
4 BEGIN
5 V_sum :=f_get_salary(10,emp_count => v_num);
6 DBMS_OUTPUT.PUT_LINE('10号部门工资总和:'||v_sum||',人数:'||v_num);
7 end;
8 /
10号部门工资总和:4400,人数:1
PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed.
3 存储过程
3.1 建立过程
创建存储过程
在 ORACLE SERVER上创建存储过程,能够被多个应用程序调用,能够向存储过程传递参数,也能够向存储过程传回参数.
建立过程语法:
CREATE [OR REPLACE] PROCEDURE procedure_name
([arg1 [ IN | OUT | IN OUT ]] type1 [DEFAULT value1],
[arg2 [ IN | OUT | IN OUT ]] type2 [DEFAULT value1]],
......
[argn [ IN | OUT | IN OUT ]] typen [DEFAULT valuen])
[ AUTHID DEFINER | CURRENT_USER ]
{ IS | AS }
<声明部分>
BEGIN
<执行部分>
EXCEPTION
<可选的异常错误处理程序>
END procedure_name;
说明:相关参数说明参见函数的语法说明。
例3.删除指定员工记录;
CREATE OR REPLACE PROCEDURE P_DelEmployees
(v_empno IN employees.employee_id%TYPE)
AS
No_result EXCEPTION;
BEGIN
DELETE FROM employees WHERE employee_id = v_empno;
IF SQL%NOTFOUND THEN
RAISE no_result;
END IF;
DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'的员工已被删除!');
EXCEPTION
WHEN no_result THEN
DBMS_OUTPUT.PUT_LINE('舒适提示:你须要的数据不存在!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END P_DelEmployees;
/
3.2 调用存储过程
存储过程创建完成后,只要经过受权,用户就能够在SQLPLUS 、ORACLE开发工具或第三方开发工具中来调用运行。对于参数的传递也有三种:按位置传递、按名称传递和组合传递,传递方法与函数的同样。ORACLE 使用EXECUTE 语句来实现对存储过程的调用:
EXEC[UTE] procedure_name( parameter1, parameter2…);
SQL> exec P_DelEmployees(300);
舒适提示:你须要的数据不存在!
PL/SQL procedure successfully completed.
SQL> declare
2 v_Employeesid number;
3 begin
4 v_Employeesid:=300;
5 P_DelEmployees(v_Employeesid);
6 end;
7 /
舒适提示:你须要的数据不存在!
PL/SQL procedure successfully completed.
3.3 AUTHID
过程当中的AUTHID 指令能够告诉ORACLE ,这个过程使用谁的权限运行.默任状况下,存储过程会做为调用者的过程运行,可是具备设计者的特权.这称为设计者权利运行.
与过程相关数据字典
USER_SOURCE, ALL_SOURCE, DBA_SOURCE, USER_ERRORS,
ALL_PROCEDURES,USER_OBJECTS,ALL_OBJECTS,DBA_OBJECTS
相关的权限:
CREATE ANY PROCEDURE
DROP ANY PROCEDURE
在SQL*PLUS 中,能够用DESCRIBE 命令查看过程的名字及其参数表。
DESC[RIBE] Procedure_name;
删除过程和函数
1.删除过程
可使用DROP PROCEDURE命令对不须要的过程进行删除,语法以下:
DROP PROCEDURE [user.]Procudure_name;
2.删除函数
可使用DROP FUNCTION 命令对不须要的函数进行删除,语法以下:
DROP FUNCTION [user.]Function_name;
使用过程与函数具备以下优势:
一、共同使用的代码能够只须要被编写和测试一次,而被须要该代码的任何应用程序(如:.NET、C++、JAVA、VB程序,也能够是DLL库)调用。
二、这种集中编写、集中维护更新、你们共享(或重用)的方法,简化了应用程序的开发和维护,提升了效率与性能。
三、这种模块化的方法,使得能够将一个复杂的问题、大的程序逐步简化成几个简单的、小的程序部分,进行分别编写、调试。所以使程序的结构清晰、简单,也容易实现。
四、能够在各个开发者之间提供处理数据、控制流程、提示信息等方面的一致性。
五、节省内存空间。它们以一种压缩的形式被存储在外存中,当被调用时才被放入内存进行处理。而且,若是多个用户要执行相同的过程或函数时,就只须要在内存中加载一个该过程或函数。
六、提升数据的安全性与完整性。经过把一些对数据的操做放到过程或函数中,就能够经过是否授予用户有执行该过程或的权限,来限制某些用户对数据进行这些操做。
过程与函数的相同功能有:
一、 都使用IN模式的参数传入数据、OUT模式的参数返回数据。
二、 输入参数均可以接受默认值,均可以传值或传引导。
三、 调用时的实际参数均可以使用位置表示法、名称表示法或组合方法。
四、 都有声明部分、执行部分和异常处理部分。
五、 其管理过程都有建立、编译、受权、删除、显示依赖关系等。
使用过程与函数的原则:
一、若是须要返回多个值和不返回值,就使用过程;若是只须要返回一个值,就使用函数。
二、过程通常用于执行一个指定的动做,函数通常用于计算和返回一个值。
三、能够SQL语句内部(如表达式)调用函数来完成复杂的计算问题,但不能调用过程。因此这是函数的特点。