Oracle基础知识3----存储过程、存储函数、out参数、包
来源:互联网 发布:樱井知香 喷泉 编辑:程序博客网 时间:2024/05/10 02:26
测试数据来源:http://blog.csdn.net/ochangwen/article/details/51297893
存储在数据库中供所有用户程序调用的子程序叫存储过程、存储函数。
二者相同点:完成特定功能的程序二者区别:存储函数可以用return语句返回值,而存储过程不能。
一、存储过程
1-1.创建和使用存储过程
用create procedure命令建立存储过程和存储函数语法:create [or replace] procedure 过程名(参数列表)
as plsql子程序体;
/*第一个存储过程:打印Hello World调用存储过程:1.exec sayhelloworld();2.再写一个存储过程,调用过程 begin sayhelloworld(); sayhelloworld(); end;*/create or replace procedure sayhelloworldas --说明部分begin dbms_output.put_line('Hello World');end;SQL> set serveroutput on;SQL> exec sayhelloworld();Hello WorldSQL> begin 2 sayhelloworld(); 3 sayhelloworld(); 4 end; 5 /Hello WorldHello World
1-2.带参数的存储过程
举例:为指定的员工,涨100块钱的工资;并且打印涨前和涨后的薪水。
drop table emp; create table emp(empno number(5),ename varchar2(10), sal number(10,2), deptno number(4) ); insert into emp(empno,ename,sal,deptno)values(1001,'Tom1',1000,10); insert into emp(empno,ename,sal,deptno)values(1002,'Tom2',2000,20); /*如何调用:begin raiseSalry(1001); raiseSalry(1002); commit; //这时提交可以保证上面的操作是在同一个事务里。end;*/--参数需要指定是输入(in)还是输出(out)create or replace procedure raiseSalry(eno in number)as --定义一个变量保存涨前的薪水 psal emp.sal%type;begin --得到员工涨前的薪水 select sal into psal from emp where empno=eno; --给该员工涨100 update emp set sal = sal +100 where empno=eno; --需不需要commit? 一般不在存储过程/函数中提交或回滚 DBMS_OUTPUT.PUT_LINE('涨工资前的薪水'||psal||'涨工资后的薪水'||(psal+100));end;SQL> begin 2 raiseSalry(1001); 3 raiseSalry(1002); 4 commit; 5 end; 6 /涨工资前的薪水1000涨工资后的薪水1100涨工资前的薪水2000涨工资后的薪水2100至于如何调试,想看百度。
二、存储函数
函数(Function)为一命名的存储程序,可带参数,并返回一计算值函数和过程的结构类似,但必须有一个return子句,用于返回函数值
创建存储函数的语法:
create [or replace] function 函数名(参数列表)
return 函数值类型
as plsql子程序体;
--存储函数:查询某个员工的年收入create or replace function queryemp_income(eno in number) return numberas --定义变量接收薪水和奖金 p_sal emp.sal%type; p_comm emp.comm%type;begin select sal,comm into p_sal,p_comm from emp where empno=eno; --nvl为遇空函数,如果p_comm为空则返回0 return nvl(p_comm,0)+p_sal*12;end;
三、其它知识点
3-1.in和out参数
一般来讲,存储过程和存储函数的区别在于存储函数可以有一个返回值;而存储过程没有返回值。
存储过程和存储函数都可以有out参数和多个out参数
存储过程可以通过out参数来实现返回值
什么时候用存储过程/函数?
原则:如果只有一个返回值,用存储函数;否则用存储过程。
--out参数:查询某个员工姓名,月薪和职位create or replace procedure queryEmpInform(eno in number,pename out varchar2, psal out number, pjob out varchar2)asbegin --得到该员工的姓名,月薪和职位 select ename,sal,job into pename,psal,pjob from emp where empno=eno;end;思考:
1.查询某个员工的所有信息 --> out参数太多?
2.查询某个部门所有员工的所有信息 --> out中返回集合?
3-2.在应用程序中访问存储过程
下面一个实例:在java应用程序中访问存储过程/函数1).首先先建一个java工程,将D:\oracle\product\10.2.0\db_3\jdbc\lib\ojdbc14.jar包build pat
工具类:
package demo.utils;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCUtils {private static String driver = "oracle.jdbc.OracleDriver";private static String url = "jdbc:oracle:thin:@localhost:1521:orcl";private static String user = "scott";private static String password = "tiger";// 注册数据库的驱动static{try {Class.forName(driver);} catch (ClassNotFoundException e) {e.printStackTrace();}}// 获取数据库连接public static Connection getConnection() {try {return DriverManager.getConnection(url, user, password);} catch (SQLException e) {e.printStackTrace();}return null;}// 释放数据库资源public static void release(Connection conn,Statement st,ResultSet rs){if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();} finally {//回收rs = null;}}if(st !=null){try {st.close();} catch (SQLException e) {e.printStackTrace();}finally {st = null;}}if(conn!=null){try {conn.close();} catch (SQLException e) {e.printStackTrace();}finally {conn = null;}}}}在应用程序 中访问存储过程
package demo.oracle;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.SQLException;import org.junit.Test;import demo.utils.JDBCUtils;import oracle.jdbc.OracleTypes;public class TestProcedure {/** * --out参数:查询某个员工姓名,月薪和职位 * create or replace procedure queryEmpInform * (eno in number,pename out varchar2, psal out number, pjob out varchar2) */@Testpublic void testProcedure() {String sql = "{call queryempinform(?,?,?,?)}";Connection conn = null;CallableStatement call = null;try {//得到一个链接conn = JDBCUtils.getConnection();//通过链接创建出statmentcall = conn.prepareCall(sql);//对于in参数,赋值call.setInt(1, 1002);//对于out参数,申明call.registerOutParameter(2, OracleTypes.VARCHAR);call.registerOutParameter(3, OracleTypes.NUMBER);call.registerOutParameter(4, OracleTypes.VARCHAR);//执行调用call.execute();//取出结果String name = call.getString(2);double sal = call.getDouble(3);String job = call.getString(4);System.out.println(name+"\t"+sal+"\t"+job);} catch (SQLException e) {e.printStackTrace();}finally{JDBCUtils.release(conn, call, null);}}}在应用程序 中访问存储函数
package demo.oracle;import java.sql.CallableStatement;import java.sql.Connection;import org.junit.Test;import demo.utils.JDBCUtils;import oracle.jdbc.OracleTypes;public class TestFunction {/** * --存储函数:查询某个员工的年收入 create or replace function queryemp_income(eno in number) return number */@Testpublic void testFunction() throws Exception {String sql = "{?=call queryemp_income(?)}";Connection conn = null;CallableStatement call=null;try{//得到数据库连接conn = JDBCUtils.getConnection();// 基于连接创建statementcall = conn.prepareCall(sql);//输出参数,申明call.registerOutParameter(1, OracleTypes.NUMBER);//输入参数,赋值call.setInt(2, 1001);call.execute();double income = call.getDouble(1);System.out.println("编号为1001的员工的年收入是" + income);}catch(Exception e){e.printStackTrace();}finally{JDBCUtils.release(conn, call, null);}}}
3-3.在out参数中使用光标
案例:查询某个部门中所有员工的所有信息先创建包头和包体
--包头:create or replace package mypackage as type empcursor is ref cursor; procedure queryEmpList(dno in number, emplist out empcursor);end mypackage;/--包体create or replace package body mypackage as procedure queryEmpList(dno in number, empList out empcursor) as begin --打开光标 open empList for select * from emp where deptno=dno; end queryEmpList;end mypackage;在应用中访问包中的存储过程
注意,需要带上包名
package demo.oracle;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import org.junit.Test;import demo.utils.JDBCUtils;import oracle.jdbc.OracleTypes;import oracle.jdbc.driver.OracleCallableStatement;public class TestCursor {/** * --包头: * create or replace package mypackage as * type empcursor is ref cursor; * procedure queryEmpList(dno in number, emplist out empcursor); * end mypackage; */@Testpublic void testCursor() {String sql = "{call mypackage.queryEmpList(?,?)}";Connection conn = null;CallableStatement call=null;ResultSet rs = null;try{conn = JDBCUtils.getConnection();call = conn.prepareCall(sql);//对于in参数,赋值call.setInt(1, 3);//对于out参数,申明call.registerOutParameter(2, OracleTypes.CURSOR);call.execute();//取出该部门中所有员工的信息rs = ((OracleCallableStatement)call).getCursor(2);while(rs.next()) {//只取出员工的员工号,姓名和职位int empno = rs.getInt("empno");String name = rs.getString("ename");String job = rs.getString("job");System.out.println(empno+":" + name+":"+job);}}catch(Exception e){e.printStackTrace();}finally{JDBCUtils.release(conn, call, null);}}}3:刘备备:MANAGER
6:张飞飞:CLERK
7:SCOTT:CLERK
0 0
- Oracle基础知识3----存储过程、存储函数、out参数、包
- Oracle 存储过程 调用带有 out 参数的存储过程
- oracle查看包存储过程,函数,以及存储过程参数,函数参数
- 存储过程,out参数
- oracle 存储过程 函数 包
- oracle 存储过程 函数 包
- oracle存储过程,函数,包
- oracle 存储过程,存储函数,包
- Oracle基础知识(二十二) - 存储过程in out inout三种参数模式
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- oracle 创建,删除存储过程,参数传递,创建,删除存储函数,存储过程和函数的查看,包,系统包
- Oracle存储过程in、out、in out 模式参数
- Oracle存储过程in、out、in out 模式参数
- oracle存储过程IN,OUT,IN OUT参数
- Linux C语言连接MySQL 增删改查操作
- HDU 1017 (水+)
- C 时间转换
- kettle variables
- Android PullToRefresh(下拉刷新)的使用详解
- Oracle基础知识3----存储过程、存储函数、out参数、包
- 1007. Maximum Subsequence Sum (25)
- 三维凸包模板
- Android studio 导如eclipse项目
- js实现倒计时
- Linux信号小结
- git 安装 使用命令
- 计蒜客挑战难题:A+B+C问题
- js实现三级菜单