jdbc存儲過程結果集
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
//獲取第一列的列名
String name = rsmd.getCatalogName(1);
Ⅱ Java JDBC里如何取得Oracle存儲過程返回的動態結果集
創建存儲過程
sql">createorreplaceprocereproc3(stidinstudent.stuid%type,stnameoutstudent.sname%type,stphoneoutstudent.phonenumber%type,stuaddoutstudent.saddress%type)
ascountnumbernumber;
begin
selectcount(*)=stid;
ifcountnumber=1then
=stid;
=stid;
=stid;
else
dbms_output.put_line('返回值過多');
endif;
end;調用存儲過程時,要用CallabelStatement的prepareCall 方法。結構:{call 存儲過程名(?,?,...)}
在設置參數的時候,輸入參數用set,輸出參數要registerOutParameter。取出輸出參數的值可以直接用CallabelStatement的get方法
importjava.sql.CallableStatement;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importjava.sql.Types;
publicclassDao{
Stringdriver="oracle.jdbc.driver.OracleDriver";
Stringurl="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
Connectionconn=null;
CallableStatementcs=null;//PreparedStatement,Statement
ResultSetrs;
publicvoidgetConn(){
try{
Class.forName(driver);
conn=DriverManager.getConnection(url,"scott","tiger");
}catch(ClassNotFoundExceptione){
e.printStackTrace();
}catch(SQLExceptione){
e.printStackTrace();
}
}
publicvoidcallProc(){
try{
cs=conn.prepareCall("{callproc3(?,?,?,?)}");
cs.setInt(1,1);
cs.registerOutParameter(2,Types.VARCHAR);
cs.registerOutParameter(3,Types.VARCHAR);
cs.registerOutParameter(4,Types.VARCHAR);
cs.execute();
Stringname=cs.getString(2);
Stringphone=cs.getString(3);
Stringaddress=cs.getString(4);
System.out.println("Name:"+name+" Phone:"+phone+" Address:"+address);
}catch(SQLExceptione){
e.printStackTrace();
}finally{
try{
if(cs!=null)cs.close();
if(conn!=null)conn.close();
}catch(SQLExceptione){
e.printStackTrace();
}
}
}
publicstaticvoidmain(String[]args){
Dao=newDao();
.getConn();
.callProc();
}
}
Ⅲ java調用存儲過程返回遊標的結果集無法關閉游標的問題
在過程里判斷很簡單呀
CREATE OR REPLACE PROCEDURE TESTPROC(CUR OUT SYS_REFCURSOR)
AS
default_c SYS_REFCURSOR;
BEGIN
OPEN CUR FOR SELECT * FROM AA;
if CUR%rowcount = 0 then
CUR:=default_c;
end if;
END;
定義一個默認空游標,沒數據就返回它唄
Ⅳ 徹底搞懂JDBC的運行過程
前幾天筆者發布了博客,手寫mybatis徹底搞懂框架原理。為了幫助初學者更好理解mybatis框架,這次講解一下Java的JDBC的運行過程。
JDBC的作用
JDBC的全稱是Java DataBase Connection,也就是Java資料庫連接,我們可以用它來操作關系型資料庫。JDBC介面及相關類在java.sql包和javax.sql包里。我們可以用它來連接資料庫,執行SQL查詢,存儲過程,並處理返回的結果。
JDBC介面讓Java程序和JDBC驅動實現了松耦合,使得切換不同的資料庫變得更加簡單。
JDBC的連接步驟
執行一次JDBC連接,分六個步驟進行:
1. 導入包
在程序中包含資料庫編程所需的JDBC類。大多數情況下,使用 import java.sql.* 就足夠了
2. 注冊JDBC驅動程序
需要初始化驅動程序,這樣就可以打開與資料庫的通信。
3. 打開一個連接
使用DriverManager.getConnection()方法來創建一個Connection對象,它代表一個資料庫的物理連接。
4. 執行一個查詢
需要使用一個類型為Statement或PreparedStatement的對象(兩者區別看後文),並提交一個SQL語句到資料庫執行查詢。
5. 從結果集中提取數據
這一步中演示如何從資料庫中獲取查詢結果的數據。使用ResultSet.getXXX()方法來檢索的數據結果
6. 清理環境資源
在使用JDBC與數據交互操作資料庫中的數據後,應該明確地關閉所有的資料庫資源以減少資源的浪費。本文使用了try with resources方式關閉資源,這是JDK7的語法糖,讀者可自行搜索。
完整代碼如下。
JDBC的最佳實踐
JDBC是如何實現Java程序和JDBC驅動的松耦合?
JDBC API使用Java的反射機制來實現Java程序和JDBC驅動的松耦合。看一下上文的JDBC示例,你會發現所有操作都是通過JDBC介面完成的,而驅動只有在通過Class.forName反射機制來載入的時候才會出現。
這是Java核心庫里反射機制的最佳實踐之一,它使得應用程序和驅動程序之間進行了隔離,讓遷移資料庫的工作變得更簡單。
Statement和PreparedStatement區別
預編譯
創建時的區別:
執行時的區別:
由上可以看出,PreparedStatement有預編譯的過程,已經綁定sql,之後無論執行多少次,都不會再去進行編譯,而Statement 不同,如果執行多次,則相應的就要編譯多少次sql,所以從這點看,PreparedStatement的效率會比Statement要高一些。PreparedStatement是預編譯的,所以可以有效的防止SQL注入等問題
佔位符
PrepareStatement可以替換變數在SQL語句中可以包含?,可以用?替換成變數。
而Statement只能用字元串拼接。
JDBC的ResultSet
在查詢資料庫後會返回一個ResultSet,它就像是查詢結果集的一張數據表。
ResultSet對象維護了一個游標,指向當前的數據行。開始的時候這個游標指向的是第一行。如果調用了ResultSet的next()方法游標會下移一行,如果沒有更多的數據了,next()方法會返回false。可以在for循環中用它來遍歷數據集。
默認的ResultSet是不能更新的,游標也只能往下移。也就是說你只能從第一行到最後一行遍歷一遍。不過也可以創建可以回滾或者可更新的ResultSet,像下面這樣。
當生成ResultSet的Statement對象要關閉或者重新執行或是獲取下一個ResultSet的時候,ResultSet對象也會自動關閉。
可以通過ResultSet的getter方法,傳入列名或者從1開始的序號來獲取列數據。
ResultSet的不同類型
根據創建Statement時輸入參數的不同,會對應不同類型的ResultSet。如果你看下Connection的方法,你會發現createStatement和prepareStatement方法重載了,以支持不同的ResultSet和並發類型。
ResultSet對象有三種類型。
ResultSet有兩種並發類型。
Ⅳ 1,如何在JDBC裡面調用一個存儲過程
最近做一個自動發郵件的schele,由於取數據的sql太長,直接分割很麻煩,就想到調用PL/SQL,網上查了資料做了練習,在此做下小結。
1、只有輸入參數而沒有返回結果的存儲過程。
sql:
1 create or replace procere prc_1(deptno in number,dname in varchar2,loc in varchar2)
2 is
3 begin
4 insert into dept values(deptno,dname,loc);
5 end prc_1;
java:
1 static void test1(){
2 Connection conn=null;
3 CallableStatement csmt=null;
4 try {
5 conn=JDBCUtils.getConnection();
6 conn.setAutoCommit(false);
7 csmt=conn.prepareCall("call prc_1(?,?,?)");
8 csmt.setInt(1,80);
9 csmt.setString(2,"ioc");
10 csmt.setString(3,"fhp");
11 csmt.execute();
12 conn.commit();
13 System.out.println("success insert data");
14 } catch (SQLException e) {
15 e.printStackTrace();
16 }
17 }
2、有輸入參數且有一個返回值的存儲過程。
sql:
1 create or replace procere prc_2(p_deptno in number,p_loc out varchar2) is
2 begin
3 select loc into p_loc from dept where deptno=p_deptno;
4 end prc_2;
