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