【Java EE 學習 29 下】【JDBC編程中操做Oracle數據庫】【調用存儲過程的方法】

疑問:怎樣判斷存儲過程執行以後返回值是否爲空。java

1、鏈接oracle數據庫sql

  1.須要的jar包:在安裝的oracle中就有,因此不須要到官網下載,個人oracle11g下:D:\app\kdyzm\product\11.2.0\dbhome_1\jdbc\lib,文件夾中有若干.jar文件,選擇ojdbc6.jar便可。數據庫

  2.鏈接oracleoracle

    驅動位置:oracle.jdbc.OracleDriverapp

    url寫法:jdbc:oracle:thin:@localhost:1521:orcl函數

  3.JDBCUtilsoop

package com.kdyzm.dbutils;

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 final String driver="oracle.jdbc.driver.OracleDriver";
    private static final String url="jdbc:oracle:thin:@localhost:1521:orcl";
    private static final String username="scott";
    private static final String password="tiger";
    static
    {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new ExceptionInInitializerError("Oracle數據庫鏈接初始化失敗!");
        }
    }
    //獲取Connection鏈接的方法
    public static Connection getConnection()
    {
        Connection conn=null;
        try {
            conn=DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
    
    //釋放資源的標準方法
    public static void free(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;
                            }
                        }
                    }
                }
            }
        }
    }
}

  4.測試鏈接測試

package com.kdyzm.test;

import java.sql.Connection;

import com.kdyzm.dbutils.JDBCUtils;

/*
 * 測試與Oracle數據庫之間的鏈接
 */
public class TestConnection {
    public static void main(String[] args) {
        Connection conn=JDBCUtils.getConnection();
        System.out.println(conn);
        JDBCUtils.free(conn, null, null);
    }
}

2、調用存儲過程fetch

  1.使用CallableStatement標準接口。url

    java.sql.Statement

      |--java.sql.CallableStatement

  建立存儲過程:

create or replace procedure searchEmpByEmpno(pempno in NUMBER,pename out varchar2,
                                              pjob out varchar2,psal out number)
as
begin
  select ename,job,sal into pename,pjob,psal from emp where empno=pempno;
end;

  2.調用存儲過程

package com.kdyzm.test;
/*
 * 測試oracle調用存儲過程,並獲得返回值。
 */
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import oracle.jdbc.OracleTypes;
import org.junit.Test;
import com.kdyzm.dbutils.JDBCUtils;

public class TestProcedure {
    @Test
    public void testProcedure()
    {
        Connection conn=null;
        ResultSet rs=null;
        CallableStatement cs=null;
        //SQL語句的形式:{call <procedure-name>[(<arg1>,<arg2>, ...)]}
        String sql="{call searchEmpByEmpno(?,?,?,?)}";//這裏的存儲過程擁有四個參數,第一個是in類型的,其他的是out類型的。
        try
        {
            conn=JDBCUtils.getConnection();
            cs=conn.prepareCall(sql);            //獲得CallableStatement對象
            cs.setInt(1, 7566);                    //設置in值
            
            //註冊三個輸出值
            cs.registerOutParameter(2, OracleTypes.VARCHAR);
            cs.registerOutParameter(3, OracleTypes.VARCHAR);
            cs.registerOutParameter(4, OracleTypes.DOUBLE);
            //執行存儲過程
            cs.execute();
            //獲得返回結果
            String ename=cs.getString(2);
            String job=cs.getString(3);
            double sal=cs.getDouble(4);
            System.out.println(ename+" 的工做是: "+job);
            System.out.println(ename+" 的薪水是: "+sal);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally{
            JDBCUtils.free(conn, cs, rs);
        }
    }
}

3、調用存儲函數

  1.原本沒有什麼不一樣之處,但這裏因爲任性使然,故展現一二,建立存儲函數

create or replace function myfun(fempno in number)
return VARCHAR2
as
  fename VARCHAR2(20);
begin
  select ename into fename from emp where empno=fempno;
  return fename;
end;

  2.調用存儲函數

package com.kdyzm.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import oracle.jdbc.OracleTypes;
import com.kdyzm.dbutils.JDBCUtils;
/*
 *測試調用存儲函數。
 */
public class TestFunction {
    public static void main(String[] args) {
        Connection conn=null;
        ResultSet rs=null;
        CallableStatement cs=null;
//        {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
        String sql="{?=call myfun(?)}";
        try
        {
            conn=JDBCUtils.getConnection();
            cs=conn.prepareCall(sql);
            cs.registerOutParameter(1, OracleTypes.VARCHAR);
            cs.setInt(2, 7521);
            cs.execute();
            String ename=cs.getString(1);
            System.out.println("查詢結果爲:"+ename);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally{
            JDBCUtils.free(conn, cs, rs);
        }
    }
}

3、調用帶有遊標返回值的存儲過程

  1.首先建立存儲過程,這裏須要使用包

    (1)聲明包

--聲明包
CREATE OR REPLACE
PACKAGE MYPACKAGE AS

  type empcursor is REF CURSOR;
  PROCEDURE queryEmpList(pempno in NUMBER,empList out empcursor);

END MYPACKAGE;

    (2)實現包體

CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS

  PROCEDURE queryEmpList(pempno in NUMBER,empList out empcursor) AS
  BEGIN
    open empList for select * from emp where pempno=empno;
  END queryEmpList;

END MYPACKAGE;

    (3)PL/SQL匿名塊測試

--測試帶有遊標的out參數。
set serveroutput on;
declare
  pempno number;
  empList mypackage.empcursor;
  empRow emp%rowtype;
begin 
  pempno:=7369;
  mypackage.queryemplist(pempno,empList);
  --open emplist;--注意必定不要再次open,由於遊標只能打開一次,不然會報錯。
    loop 
      fetch emplist into empRow;
      exit when emplist%notfound;
      dbms_output.put_line(empRow.ename||'的工資是:'||empRow.sal);
    end loop;
    null;
  close emplist;
end;
/

  2.調用存儲過程

package com.kdyzm.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;

import oracle.jdbc.OracleTypes;
import oracle.jdbc.OracleCallableStatement;
import com.kdyzm.dbutils.JDBCUtils;

/*
 * 測試帶有遊標返回值的存儲過程
 * @author kdyzm
 *
 */
public class TestProcedureWithCursor {
    public static void main(String[] args) {
        Connection conn=null;
        CallableStatement cs=null;
        ResultSet rs=null;
        String sql="{call mypackage.queryemplist(?,?)}";
        try
        {
            conn=JDBCUtils.getConnection();
            cs=conn.prepareCall(sql);
            cs.setInt(1, 7521);
            cs.registerOutParameter(2, OracleTypes.CURSOR);
            cs.execute();
            OracleCallableStatement ocs=(OracleCallableStatement)cs;
            rs=ocs.getCursor(2);
            while(rs.next())
            {
                System.out.print(rs.getInt("empno")+" ");
                System.out.print(rs.getString("ename")+" ");
                System.out.print(rs.getString("JOB")+" ");
                System.out.print(rs.getInt("MGR")+" ");
                System.out.print(rs.getDate("HIREDATE")+" ");
                System.out.print(rs.getDouble("SAL")+" ");
                System.out.print(rs.getInt("COMM")+" ");
                System.out.print(rs.getInt("DEPTNO")+" ");
                System.out.println();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        finally{
            JDBCUtils.free(conn, cs, rs);
        }
    }
}

  3.運行結果

  

相關文章
相關標籤/搜索