Oracle存储过程简介 什么是存储过程 在oracle中,存储过程是为了完成特定功能的SQL语句集,编译后存储在数据库中,用户通过指定存储过程名字并给出参数(如果该存储过程带有参数)来调用存储过程。
存储过程有什么优点
效率高 存储过程编译一次后,就会存到数据库,每次调用时都直接执行,而如果是执行普通sql语句,每次都要编译后再执行,效率显然更低一些。
复用性高 存储过程往往是针对一个特定的功能编写的,当再需要完成这个特定的功能时,可以再次调用该存储过程。
减少网络传输 存储过程编译好会放在数据库,我们在远程调用时,不会传输大量的字符串类型的sql语句L;另外因为一个存储过程中可以执行一系列的操作,程序中如果要执行复杂的sql操作,不需要多次连接数据库执行多条sql。
安全性高 完成某个特定功能的存储过程一般只有特定的用户可以使用,具有使用身份限制,更安全。
存储过程的语法格式 基本结构 Oracle存储过程包含三部分:过程声明,执行过程部分,存储过程异常(可写可不写,要增强脚本的容错性和调试的方便性那就写上异常处理)
无参存储过程 无参存储过程是指存储过程没有输入、输出参数,如下就是一个简单的无参存储过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 CREATE OR REPLACE PROCEDURE pro_01AS v_id NUMBER := 100 ; v_name VARCHAR2; v_age NUMBER; BEGIN SELECT student_name,student_age INTO v_name,v_age FROM student where student_id= v_id; dbms_output.put_line('姓名:' || v_name|| ',年龄:' || v_age); WHEN OTHERS THEN dbms_output.put_line('OTHER_EXCEPTION:' || SQLERRM); END ;
有参存储过程 我们像调用Java中的方法一样,给存储过程定义输入、输出参数,比如对于上面的这个例子,学生id可以通过参数传入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 CREATE OR REPLACE PROCEDURE pro_02( i_id IN NUMBER; o_resultcode OUT VARCHAR2, o_msg OUT VARCHAR2 ) AS v_name VARCHAR2; v_age NUMBER; BEGIN SELECT student_name,student_age INTO v_name,v_age FROM student where student_id= v_id; dbms_output.put_line('姓名:' || v_name|| ',年龄:' || v_age); o_resultcode := 0 ; o_msg := 'SUCCESS' ; WHEN OTHERS THEN dbms_output.put_line('OTHER_EXCEPTION:' || SQLERRM); o_resultcode := -1 ; o_msg := 'OTHER_EXCEPTION:' || SQLERRM; END ;
存储过程参数的几种类型:
in 表示传入的参数,是参数的默认模式 ,例如i_id IN NUMBER和i_id NUMBER语义是相同的。
out 表示返回的参数,该参数的值可以传递回调用它的过程。
in out 表示此参数可以向该存储过程中传递值,也可以将某个值传出去。
扩展 在存储过程中既可以使用各种循环判断,也可以有事务的控制,比如我们需要写一个存储过程来统计不同月份各个城市的订单量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 CREATE OR REPLACE PROCEDURE pro_03( i_month IN NUMBER; o_resultcode OUT VARCHAR2, o_msg OUT VARCHAR2 ) AS v_count NUMBER := 0 ; cursor cursor_stat is select month , citycode, count (* ) ordercount from order group by month , citycode; BEGIN delete from order_stat where month = i_month; for stat_item in cursor_stat loop insert into order_stat(month , citycode, ordercount) values (stat_item.month, stat_item.citycode, stat_item.ordercount); v_count := v_count + 1 ; if mod (v_count, 200 ) = 0 then commit ; end loop; commit ; o_resultcode := 0 ; o_msg := 'SUCCESS' ; WHEN OTHERS THEN dbms_output.put_line('OTHER_EXCEPTION:' || SQLERRM); o_resultcode := -1 ; o_msg := 'OTHER_EXCEPTION:' || SQLERRM; END ;
存储过程也可以返回结果集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE OR REPLACE PROCEDURE pro_04( cur_data OUT SYS_REFCURSOR ) AS BEGIN open cur_data for select id, name, age from student; END ;
其它 查询存储过程的编译错误 存储过程如果问题,在编译时时会报错的,编译界面也可以看到异常信息。另外编译的异常信息也会记录到数据库表,可通过如下sql查询。
1 select * from SYS.USER_ERRORS where NAME = upper ('${存储过程的名称}' );