目录
一,存储过程和存储函数简介
1,简介
2,异同
3,用无参的存储过程和函数程序实现打印“Hello word!”
二,存储过程
1,简介
2,例子
(1)创建输入参数的存储过程 -- 根据id删除数据
(2)创建带有输出参数的存储过程 -- 根据传入参数求结果
(3)创建带有输入输出参数的存储过程 -- 实现两个数的交换
三,存储函数
1,简介
2,例子 参数类型:输入参数,输出参数,输入输出参数
四,调用和删除
1,调用
(1)EXEC
(2)BIGIN END;
(3)CALL
2,删除
存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升.
oracle中的存储函数,和系统内的函数类似,可以像调用系统函数一样调用存储函数。它与存储过程的唯一区别就是存储过程没有return返回值,存储函数可以与存储过程互换,存储函数可以在存储过程中调用。
存储过程和存储函数的相同点:
都是数据库对象(表,视图,索引,序列,同义词,过程和函数)
存储在数据库中被命名的PLSQL块
供所有用户程序调用
完成特定功能的子程序
存储过程和存储函数的比较:
(1)关键字
存储过程:PROCEDURE
存储函数:FUNCTION
(2)调用方式
存储过程的调用方式: 存储函数的调用方式
独立的过程调用语句 以表达式方式调用
BEGIN DECLARE
procedure_name; V_RESULT TYPE;
END; BEGIN
V_RESULT := function_name;
END;
(3)return返回值
是否有return返回值 : 存储过程无返回参数,存储函数有返回参数。
(4)创建的目的
存储过程:完成一系列的数据处理
存储函数:或得函数返回值
(5)返回值的实现
存储过程:可以通过一个或多个out参数实现返回值;
存储函数:可以通过自身和一个或多个out参数实现返回值;
一般原则:如果只有一个返回值,用存储函数处理,使用方便。
(6)参数默认值
都可以在声明过程或函数参数时,使用DEFAULT关键字为输入参数指定默认值。
语句
--创建存储过程
CREATE OR REPLACE PROCEDURE FIRST_PROCEDURE
IS
BEGIN
DBMS_OUTPUT.PUT_LINE('我是过程');
DBMS_OUTPUT.PUT_LINE('Hello word!');
END;
--创建函数
CREATE OR REPLACE FUNCTION FIRST_FUNCTION
RETURN VARCHAR2
IS
BEGIN
DBMS_OUTPUT.put_line('我是函数');
RETURN 'Hello word!';
END;
--测试
BEGIN
FIRST_PROCEDURE;--调用存储过程
DBMS_OUTPUT.put_line(FIRST_FUNCTION);--调用存储函数
END;
CALL FIRST_PROCEDURE();--调用存储过程
效果
我是过程
Hello word!
我是函数
Hello word!
不需要添加commit;指令,原则上说这个跟JAVA的异常一样,谁使用谁处理。
语法
--存储过程的与语法
CREATE [OR REPLACE] PROCEDURE PROCEDURE_NAME
[(ARGMENT1 [IN|OUT|IN OUT]) TYPE,(ARGMENT1 [IN|OUT|IN OUT]) TYPE]
[IS|AS]
--声明部分,类型,变量的说明
BEGIN
--执行部分
EXCEPTION
--可选的异常错误处理部分
END;
前期准备
-- Create table
create table TEXT_TABLE
(
id VARCHAR2(40),
name VARCHAR2(40)
)
SQL%NOTFOUND 是一个布尔值。与最近的sql语句(update,insert,delete,select)发生交互,当最近的一条sql语句没有涉及任何行的时候,则返回true。否则返回false。这样的语句在实际应用中,是非常有用的。例如要update一行数据时,如果没有找到,就可以作相应操作。
CREATE OR REPLACE PROCEDURE PROCEDURE_IN
(V_ID IN TEXT_TABLE.ID%TYPE)
IS
BEGIN
DELETE FROM TEXT_TABLE WHERE ID = V_ID; --根据id删除数据
IF SQL%NOTFOUND THEN --判断是否删除成功
-- -20000~ -20999之间
RAISE_APPLICATION_ERROR(-20008,'该数据不存在!'||V_ID);
ELSE
DBMS_OUTPUT.put_line('删除成功!');
END IF;
END;
--测试
declare
V_ID VARCHAR2(40) :='1';
BEGIN
PROCEDURE_IN(V_ID);
END;
效果
执行第一次:
删除成功!
执行第二次:
CREATE OR REPLACE PROCEDURE PROCEDURE_IN_AND_OUT
(V_ID IN VARCHAR2(40), V_NAME OUT VARCHAR2(40))
IS
BEGIN
SELECT COUNT(*)
INTO V_NAME
FROM TEXT_TABLE
WHERE ID < V_ID ;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.put_line('没有此数据!');
WHEN OTHERS THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;
--测试
declare
V_ID VARCHAR2(40) := '3';
V_NAME VARCHAR2(40) ;
BEGIN
PROCEDURE_IN_AND_OUT(V_ID,V_NAME);
DBMS_OUTPUT.put_line('V_NAME = '||V_NAME);
END;
效果
V_NAME = 1
CREATE OR REPLACE PROCEDURE PROCEDURE_INOUT
(v_num1 IN OUT NUMBER, v_num2 IN OUT NUMBER)
AS
v_temp NUMBER := 0;
BEGIN
v_temp:= v_num1;
v_num1:= v_num2;
v_num2:= v_temp;
END;
--测试
declare
v_1 NUMBER := 1;
v_2 NUMBER := 100;
BEGIN
DBMS_OUTPUT.put_line('执行前 v_1 = '||v_1||' v_2 = '||v_2);
PROCEDURE_INOUT(v_1,v_2);
DBMS_OUTPUT.put_line('执行后 v_1 = '||v_1||' v_2 = '||v_2);
END;
效果
执行前 v_1 = 1 v_2 = 100
执行后 v_1 = 100 v_2 = 1
语法
--存储函数的与语法
CREATE [OR REPLACE] FUNCTION FUNCTION_NAME
[(ARGMENT1 [IN|OUT|IN OUT]) TYPE,(ARGMENT1 [IN|OUT|IN OUT]) TYPE]
RETURN return_type
[IS|AS]
--声明部分,类型,变量的说明
BEGIN
--执行部分,函数体
EXCEPTION
--可选的异常错误处理部分
END;
--1:创建带有输入参数的存储函数
CREATE OR REPLACE FUNCTION FUNCTION1
(v_num IN NUMBER)
RETURN NUMBER
IS
v_return NUMBER;
BEGIN
v_return := v_num;
RETURN v_return;
END;
--2:创建带有输出参数的存储函数
CREATE OR REPLACE FUNCTION FUNCTION2
(v_num1 IN NUMBER, v_num2 OUT NUMBER)
RETURN NUMBER
IS
v_return NUMBER;
BEGIN
v_return := v_num1;
v_num2 := v_num1+1;
RETURN v_return;
END;
--3:创建带有输入输出参数的存储函数
--求两个数的平方和,并输出两个数的平方
CREATE OR REPLACE FUNCTION FUNCTION3
(v_num1 IN OUT NUMBER, v_num2 IN OUT NUMBER)
RETURN NUMBER
AS
BEGIN
v_num1 := v_num1*v_num1;
v_num2 := v_num2*v_num2;
RETURN v_num1+v_num2;
END;
-- 测试
declare
v_num1 NUMBER := 1;
v_num2 NUMBER ;
v_num3 NUMBER := 2;
BEGIN
DBMS_OUTPUT.put_line('FUNCTION1 = '||FUNCTION1(v_num1));
DBMS_OUTPUT.put_line('FUNCTION2 = '||FUNCTION2(v_num1,v_num2) ||' v_num2 = '||v_num2);
DBMS_OUTPUT.put_line('执行前 v_num1 = '||v_num1||' v_num3 = '||v_num3);
DBMS_OUTPUT.put_line('FUNCTION3 = '||FUNCTION3(v_num1,v_num3) );
DBMS_OUTPUT.put_line('执行后 v_num1 = '||v_num1||' v_num3 = '||v_num3);
END;
结果
FUNCTION1 = 1
FUNCTION2 = 1 v_num2 = 2
执行前 v_num1 = 1 v_num3 = 2
FUNCTION3 = 5
执行后 v_num1 = 1 v_num3 = 4
调用无参数的存储过程:直接引用过程名称即可
调用带有输入参数的存储过程:
调用带有输出参数的存储过程:
调用带有输入输出参数的存储过程:
oracle使用EXECUTE语句实现对存储过程的调用;
EXEC[UTE] procedure_name(parameter1,parameter1);
在PLSQL代码中直接调用
BEGIN
procedure_name(parameter1,parameter1);
END;
使用DROP [关键字] 命令,语法如下
DROP PROCEDURE procedure_name;--删除过程
DROP FUNCTION FUNCTION_name;--删除函数