create or replace procedure queryEmpinfo(eno in number, pename out varchar2, psal out number, pjob out varchar2)asbegin select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;end;复制代码
--查询某个员工的年收入create or replace function queryEmpIncome(eno in number)return numberas psal emp.sal%type; pcomm emp.comm%type;begin select sal,comm into psal,pcomm from emp where empno=eno; --返回年收入 return psal*12+nvl(pcomm,0);end;复制代码
--在out参数中使用光标查询某个部门中全部员工的全部信息--包头CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor; procedure queryEmpList(dno in number,empList out empcursor);END MYPACKAGE;--包体CREATE OR REPLACEPACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS BEGINopen empList for select * from emp where deptno=dno; END queryEmpList;END MYPACKAGE;复制代码
import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import oracle.jdbc.driver.OracleCallableStatement;import oracle.jdbc.driver.OracleTypes;import org.junit.Test;public class TestOracle {/* * CallableStatement 接口 * 调用存储函数,等号左边有一个返回值 * {?= call <procedure-name>[(<arg1>,<arg2>, ...)]} * 调用存储过程. 没有返回值 {call <procedure-name>[(<arg1>,<arg2>, ...)]} * *//*存储过程 查询某个员工的姓名 月薪 职位 * create or replace procedure queryEmpinfo(eno in number, pename out varchar2, psal out number, pjob out varchar2) */@Testpublic void testProcedure(){//{call <procedure-name>[(<arg1>,<arg2>,...)]}String sql = "{call queryEmpinfo(?,?,?,?)}";//4个问号中,第一个是输入参数,其他是输出参数Connection conn = null;//要用CallableStatement这个接口,用于执行 SQL 存储过程的接口CallableStatement call = null;try { conn = JDBCUtils.getConnection(); call = conn.prepareCall(sql);//对于in参数,须要赋值call.setInt(1,7839);//对于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+"\t"); } catch (SQLException e) { e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null} }/*存储函数 查询某个员工的姓名,月薪和职位 * create or replace function queryEmpIncome(eno in number) return number */@Testpublic void testFunction(){//{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}//第一个问号是函数的返回值,第二个问号是输入参数. 返回值的做用和输出参数是同样的.String sql = "{?=call QUERYEMPINCOME(?)}";//这个call后面的存储过程名或者是存储函数名大写或者是小写是没有要求的.Connection conn = null;//要用CallableStatement这个接口,用于执行 SQL 存储过程的接口CallableStatement call = null;try { conn = JDBCUtils.getConnection(); call = conn.prepareCall(sql);//对于in参数,赋值call.setInt(2,7839);//对于out参数,申明call.registerOutParameter(1, OracleTypes.NUMBER); call.execute();//取出结果//取出结果double income = call.getDouble(1); System.out.println(income); } catch (SQLException e) { e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, null);//没有最后一个参数就传入null} }/* 查询某个部门中全部员工的全部信息 包头 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; */@Testpublic void testCursor(){//{call <procedure-name>[(<arg1>,<arg2>, ...)]}String sql = "{call MYPACKAGE.queryEmpList(?,?)}"; Connection conn = null; CallableStatement call = null;//有游标,就有结果集ResultSet rest = null;try { conn = JDBCUtils.getConnection(); call = conn.prepareCall(sql);//对于in参数,赋值call.setInt(1, 20);//对于out参数,申明call.registerOutParameter(2, OracleTypes.CURSOR); call.execute();//取出集合//这个地方要强转!!!OracleCallableStatement是抽象类,继承了CallableStatement//不强转没有getCursor()方法...rest = ((OracleCallableStatement)call).getCursor(2);while(rest.next()){ String name = rest.getString("ename");double sal = rest.getDouble("sal"); System.out.println(name+"\t"+sal); } }catch (Exception e) { e.printStackTrace(); }finally{ JDBCUtils.release(conn, call, rest);//上面打开了光标,再这个地方关闭结果集rest,也就关闭了光标} } }复制代码
create or replace procedure queryEmpinfo(eno in number, pename out varchar2, psal out number, pjob out varchar2) as begin select ename,sal,empjob into pename,psal,pjob from emp where empno=eno; end;复制代码
可是①若是要查询一个员工的全部信息,而这个员工的信息对应的有几百列java
在存储函数中括号的函数要把这几百列都声明出来?sql
②若是要查询某个部门中全部员工的全部信息...这个信息对应的是一个集合.数据库
第二个问题解决了第一个问题也就解决了.oracle
怎么在存储过程或者存储函数中返回一个集合.ide
学到如今有多少种方式能够表明一个集合?函数
第一个是表,第二个是select语句也能够.第三个是光标.工具
在out参数中使用光标.可是有一个要求,必需要声明一个包,包分为包头和包体.也是数据库的对象.跟表,视图,等是同样的是数据库的对象.rest
包头只负责声明,包体只负责实现.对象
--在out参数中使用光标--查询某个部门中全部员工的全部信息--包头CREATE OR REPLACE PACKAGE MYPACKAGE AS type empcursor is ref cursor; procedure queryEmpList(dno in number,empList out empcursor);END MYPACKAGE;--包体CREATE OR REPLACEPACKAGE BODY MYPACKAGE AS procedure queryEmpList(dno in number,empList out empcursor) AS BEGINopen empList for select * from emp where deptno=dno; END queryEmpList;END MYPACKAGE;复制代码
包没法在plsqldeveloper和sqldeveloper等工具中右键运行....必须经过java代码应用程序来调用执行(代码在上面)blog