當前位置:首頁 » 存儲配置 » java如何調用存儲過程

java如何調用存儲過程

發布時間: 2022-12-08 00:29:00

① 在java中調用db2存儲過程,怎樣給存儲過程傳

JDBC調用存儲過程: CallableStatement
在Java裡面調用存儲過程,寫法那是相當的固定:
Class.forName(....
Connection conn = DriverManager.getConnection(....
/**
*p是要調用的存儲過程的名字,存儲過程的4個參數,用4個?號佔位符代替
*其餘地方寫法固定
*/
CallableStatement cstmt = conn.prepareCall("{call p(?,?,?,?)}");
/**
*告訴JDBC,這些個參數,哪些是輸出參數,輸出參數的類型用java.sql.Types來指定
*下面的意思是,第3個?和第4個?是輸出參數,類型是INTEGER的
*Types後面具體寫什麼類型,得看你的存儲過程參數怎麼定義的
*/
cstmt.registerOutParameter(3, Types.INTEGER);
cstmt.registerOutParameter(4, Types.INTEGER);
/**
*在我這里第1個?和第2個?是輸入參數,第3個是輸出參數,第4個既輸入又輸出
*下面是設置他們的值,第一個設為3,第二個設為4,第4個設置為5
*沒設第3個,因為它是輸出參數
*/
cstmt.setInt(1, 3);
cstmt.setInt(2, 4);
cstmt.setInt(4, 5);
//執行
cstmt.execute();
//把第3個參數的值當成int類型拿出來
int three = cstmt.getInt(3);
System.out.println(three);
//把第4個參數的值當成int類型拿出來
int four = cstmt.getInt(4);
System.out.println(four);
//用完別忘給人家關了,後開的先關
cstmt.close();
conn.close();

JDBC調用存儲過程,掌握這一個程序足夠了.
以下是上面程序使用的存儲過程的代碼,我用的是Oracle資料庫,不過不論是什麼資料庫,對於你的程序,JDBC這一端寫法都是一樣的.

create or replace procere p
(v_a in number,v_b number,v_ret out number,v_temp in out number)
is
begin
if(v_a > v_b) then
v_ret := v_a;
else
v_ret := v_b;
end if;
v_temp := v_temp + 1;
end;

② 存儲過程如何在Java項目中調用

存儲過程在Java項目中調用:

public Object clone(){

MathHomework m = null;

/**

* 深度復制

*/

m = (MathHomework) this.clone();

m.A = (Date)this.getA().clone();

return m;

}

public Date getA(){

return A;

}

③ java 怎麼調用mysql 存儲過程

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
/*
* 對應的存儲過程
DROP PROCEDURE IF EXISTS `pro_num_user`;
delimiter ;;
CREATE PROCEDURE `pro_num_user`(IN user_name varchar(10) ,OUT count_num INT)
READS SQL DATA
BEGIN
SELECT COUNT(*) INTO count_num FROM tab_user WHERE 'name'=user_name;
END
;;
delimiter ;
*/
public class Test {
public static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
public static final String URL = "jdbc:mysql://127.0.0.1:3306/test";
public static final String USERNAME = "root";
public static final String PASSWORD = "acbee";
public static void main(String[] args) throws Exception {
test1();
test2();
}

public static void test1() throws Exception
{
Class.forName(DRIVER_CLASS);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
String sql = "{CALL pro_num_user(?,?)}"; //調用存儲過程
CallableStatement cstm = connection.prepareCall(sql); //實例化對象cstm
cstm.setString(1, "myd"); //存儲過程輸入參數
//cstm.setInt(2, 2); // 存儲過程輸入參數
cstm.registerOutParameter(2, Types.INTEGER); // 設置返回值類型 即返回值
cstm.execute(); // 執行存儲過程
System.out.println(cstm.getInt(2));
cstm.close();
connection.close();
}

public static void test2() throws Exception
{
Class.forName(DRIVER_CLASS);
Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
String sql = "{CALL pro_number(?,?,?)}"; //調用存儲過程
CallableStatement cstm = connection.prepareCall(sql); //實例化對象cstm
cstm.setInt(1, 2); // 存儲過程輸入參數
cstm.setInt(2, 2); // 存儲過程輸入參數
cstm.registerOutParameter(3, Types.INTEGER); // 設置返回值類型 即返回值
cstm.execute(); // 執行存儲過程
System.out.println(cstm.getInt(3));
cstm.close();
connection.close();

}
}

④ oracle 的存儲過程在java怎麼調用

java下實現調用oracle的存儲過程和函數
在oracle下創建一個test的賬戶,然後按一下步驟執行:
1.創建表:STOCK_PRICES

--創建表格
CREATE TABLE STOCK_PRICES(
RIC VARCHAR(6) PRIMARY KEY,
PRICE NUMBER(7,2),
UPDATED DATE );

2.插入測試數據:

--插入數據
INSERT INTO stock_prices values('1111',1.0,SYSDATE);
INSERT INTO stock_prices values('1112',2.0,SYSDATE);
INSERT INTO stock_prices values('1113',3.0,SYSDATE);
INSERT INTO stock_prices values('1114',4.0,SYSDATE);

3.建立一個返回遊標: PKG_PUB_UTILS

--建立一個返回遊標
CREATE OR REPLACE PACKAGE PKG_PUB_UTILS IS
--動態游標
TYPE REFCURSOR IS REF CURSOR;
END PKG_PUB_UTILS;

4.創建和存儲過程:P_GET_PRICE

--創建存儲過程
CREATE OR REPLACE PROCEDURE P_GET_PRICE
(
AN_O_RET_CODE OUT NUMBER,
AC_O_RET_MSG OUT VARCHAR2,
CUR_RET OUT PKG_PUB_UTILS.REFCURSOR,
AN_I_PRICE IN NUMBER
)
IS
BEGIN
AN_O_RET_CODE := 0;
AC_O_RET_MSG := '操作成功';

OPEN CUR_RET FOR
SELECT * FROM STOCK_PRICES WHERE PRICE<AN_I_PRICE;
EXCEPTION
WHEN OTHERS THEN
AN_O_RET_CODE := -1;
AC_O_RET_MSG := '錯誤代碼:' || SQLCODE || CHR(13) || '錯誤信息:' || SQLERRM;
END P_GET_PRICE;

5.創建函數:

--創建函數:F_GET_PRICE
CREATE OR REPLACE FUNCTION F_GET_PRICE(v_price IN NUMBER)
RETURN PKG_PUB_UTILS.REFCURSOR
AS
stock_cursor PKG_PUB_UTILS.REFCURSOR;
BEGIN
OPEN stock_cursor FOR
SELECT * FROM stock_prices WHERE price < v_price;
RETURN stock_cursor;
END;

6.JAVA調用存儲過程返回結果集
代碼示例:JDBCoracle10G_INVOKEPROCEDURE.java

import java.sql.*;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;

/* 本例是通過調用oracle的存儲過程來返回結果集:
* oracle 9i、10G 的jdbc由1個jar包組成:classes12.zip
*/
public class JDBCoracle10G_INVOKEPROCEDURE {
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
CallableStatement stmt = null;

String driver;
String url;
String user;
String pwd;
String sql;
String in_price;

public JDBCoracle10G_INVOKEPROCEDURE()
{
driver = "oracle.jdbc.driver.OracleDriver";
url = "jdbc:oracle:thin:@localhost:1521:ORCL";
// oracle 用戶
user = "test";
// oracle 密碼
pwd = "test";
init();
// mysid:必須為要連接機器的sid名稱,否則會包以下錯:
// java.sql.SQLException: Io 異常: Connection
// refused(DESCRIPTION=(TMP=)(VSNNUM=169870080)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
// 參考連接方式:
// Class.forName( "oracle.jdbc.driver.OracleDriver" );
// cn = DriverManager.getConnection(
// "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );

}

public void init() {
System.out.println("oracle jdbc test");
try {
Class.forName(driver);
System.out.println("driver is ok");
conn = DriverManager.getConnection(url, user, pwd);
System.out.println("conection is ok");
statement = conn.createStatement();
// conn.setAutoCommit(false);
// 輸入參數
in_price = "3.0";
// 調用函數
stmt = conn.prepareCall("call P_GET_PRICE(?,?,?,?)");
stmt.registerOutParameter(1, java.sql.Types.FLOAT);
stmt.registerOutParameter(2, java.sql.Types.CHAR);
stmt.registerOutParameter(3, oracle.jdbc.OracleTypes.CURSOR);
stmt.setString(4, in_price);
stmt.executeUpdate();
int retCode = stmt.getInt(1);
String retMsg = stmt.getString(2);
if (retCode == -1) { // 如果出錯時,返回錯誤信息
System.out.println("報錯!");
} else {
// 取的結果集的方式一:
rs = ((OracleCallableStatement) stmt).getCursor(3);
// 取的結果集的方式二:
// rs = (ResultSet) stmt.getObject(3);
String ric;
String price;
String updated;
// 對結果進行輸出
while (rs.next()) {
ric = rs.getString(1);
price = rs.getString(2);
updated = rs.getString(3);
System.out.println("ric:" + ric + ";-- price:" + price
+ "; --" + updated + "; ");
}
}

} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("close ");
}
}

public static void main(String args[])// 自己替換[]
{
new JDBCoracle10G_INVOKEPROCEDURE();
}
}

7.開發JAVA調用函數返回結果集
代碼示例:JDBCoracle10G_INVOKEFUNCTION.java

import java.sql.*;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;

/*
/* 本例是通過調用oracle的函數來返回結果集:
* oracle 9i、10G 的jdbc由1個jar包組成:classes12.zip
*/
public class JDBCoracle10G_INVOKEFUNCTION {
Connection conn = null;
Statement statement = null;
ResultSet rs = null;
CallableStatement stmt = null;

String driver;
String url;
String user;
String pwd;
String sql;
String in_price;

public JDBCoracle10G_INVOKEFUNCTION()
{
driver = "oracle.jdbc.driver.OracleDriver";
url = "jdbc:oracle:thin:@localhost:1521:ORCL";
// oracle 用戶
user = "test";
// oracle 密碼
pwd = "test";
init();
// mysid:必須為要連接機器的sid名稱,否則會包以下錯:
// java.sql.SQLException: Io 異常: Connection
// refused(DESCRIPTION=(TMP=)(VSNNUM=169870080)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
// 參考連接方式:
// Class.forName( "oracle.jdbc.driver.OracleDriver" );
// cn = DriverManager.getConnection(
// "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );
}

public void init() {
System.out.println("oracle jdbc test");
try {
Class.forName(driver);
System.out.println("driver is ok");
conn = DriverManager.getConnection(url, user, pwd);
System.out.println("conection is ok");
statement = conn.createStatement();
// conn.setAutoCommit(false);
// 輸入參數
in_price = "5.0";
// 調用函數
stmt = conn.prepareCall("{? = call F_GET_PRICE(?)}");
// stmt.registerOutParameter(1, java.sql.Types.FLOAT);
// stmt.registerOutParameter(2, java.sql.Types.CHAR);
stmt.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
stmt.setString(2, in_price);
stmt.executeUpdate();
// 取的結果集的方式一:
rs = ((OracleCallableStatement) stmt).getCursor(1);
// 取的結果集的方式二:
// rs = (ResultSet) stmt.getObject(1);
String ric;
String price;
String updated;

while (rs.next()) {
ric = rs.getString(1);
price = rs.getString(2);
updated = rs.getString(3);
System.out.println("ric:" + ric + ";-- price:" + price + "; --"
+ updated + "; ");
}

} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("close ");
}
}

public static void main(String args[])// 自己替換[]
{
new JDBCoracle10G_INVOKEFUNCTION();
}
}

⑤ java裡面怎麼調用存儲過程

最近做一個自動發郵件的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;

java:

1 static void test2(){
2 Connection conn=null;
3 CallableStatement csmt=null;
4 try {
5 conn=JDBCUtils.getConnection();
6 conn.setAutoCommit(false);
7 csmt=conn.prepareCall("call prc_2(?,?)");
8 csmt.setInt(1,70);
9 csmt.registerOutParameter(2,Types.VARCHAR);
10 csmt.execute();
11 conn.commit();
12 System.out.println("MIS位置:"+csmt.getString(2));
13 } catch (SQLException e) {
14 e.printStackTrace();
15 }
16 }

3、返回多行記錄(游標)的存儲過程。
sql:
首先要建立一個返回遊標,以便接收返回結果。

1 create or replace package testpackage is
2 type test_cursor is ref cursor;
3 end testpackage;
4
5 create or replace procere prc_3(p_cursor out testpackage.test_cursor)is
6 begin
7 open p_cursor for
8 select * from dept order by deptno;
9 end prc_3;

java:

1 static void test3(){
2 Connection conn=null;
3 CallableStatement csmt=null;
4 ResultSet rs=null;
5 try {
6 conn=JDBCUtils.getConnection();
7 conn.setAutoCommit(false);
8 csmt=conn.prepareCall("call prc_3(?)");
9 csmt.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
10 csmt.execute();
11 rs=(ResultSet) csmt.getObject(1);
12 while(rs.next()){
13 System.out.println(rs.getString("deptno")+'\t'+rs.getString("dname")+'\t'+rs.getString("loc"));
14 }
15 } catch (SQLException e) {
16 // TODO Auto-generated catch block
17 e.printStackTrace();
18 }finally{
19 JDBCUtils.free(rs, csmt, conn);
20 }
21 }

⑥ 如何使用java語言調用oracle存儲過程

1.api上的方法為 Connection.prepareCall(java.lang.String)
2.prepareCall(String sql)
throws SQLException
參數:sql - 可以包含一個或多個 '?' 參數佔位符的 SQL 語句。通常此語句是使用 JDBC 調用轉義語法指定的。
3.JDBC API 提供了一個存儲過程 SQL 轉義語法,該語法允許對所有 RDBMS 使用標准方式調用存儲過程。此轉義語法有一個包含結果參數的形式和一個不包含結果參數的形式。分別為:
{?= call <procere-name>[(<arg1>,<arg2>, ...)]}
{call <procere-name>[(<arg1>,<arg2>, ...)]}

4.示例,無返回值調用:Connection.prepareCall({ call p_test(p1,p2)})

⑦ 在JAVA中怎麼調用帶參數的存儲過程

JDBC調用存儲過程: CallableStatementx0dx0a在Java裡面調用存儲過程,寫法那是相當的固定:x0dx0aClass.forName(....x0dx0aConnection conn = DriverManager.getConnection(....x0dx0a/**x0dx0a*p是要調用的存儲過程的名字,存儲過程的4個參數,用4個?號佔位符代替x0dx0a*其餘地方寫法固定x0dx0a*/x0dx0aCallableStatement cstmt = conn.prepareCall("{call p(?,?,?,?)}");x0dx0a/**x0dx0a*告訴JDBC,這些個參數,哪些是輸出參數,輸出參數的類型用java.sql.Types來指定x0dx0a*下面的意思是,第3個?和第4個?是輸出參數,類型是INTEGER的x0dx0a*Types後面具體寫什麼類型,得看你的存儲過程參數怎麼定義的x0dx0a*/x0dx0acstmt.registerOutParameter(3, Types.INTEGER);x0dx0acstmt.registerOutParameter(4, Types.INTEGER);x0dx0a/**x0dx0a*在我這里第1個?和第2個?是輸入參數,第3個是輸出參數,第4個既輸入又輸出x0dx0a*下面是設置他們的值,第一個設為3,第二個設為4,第4個設置為5x0dx0a*沒設第3個,因為它是輸出參數x0dx0a*/x0dx0acstmt.setInt(1, 3);x0dx0acstmt.setInt(2, 4);x0dx0acstmt.setInt(4, 5);x0dx0a//執行x0dx0acstmt.execute();x0dx0a//把第3個參數的值當成int類型拿出來x0dx0aint three = cstmt.getInt(3);x0dx0aSystem.out.println(three);x0dx0a//把第4個參數的值當成int類型拿出來x0dx0aint four = cstmt.getInt(4);x0dx0aSystem.out.println(four);x0dx0a//用完別忘給人家關了,後開的先關x0dx0acstmt.close();x0dx0aconn.close();x0dx0ax0dx0aJDBC調用存儲過程,掌握這一個程序足夠了.x0dx0a以下是上面程序使用的存儲過程的代碼,我用的是Oracle資料庫,不過不論是什麼資料庫,對於你的程序,JDBC這一端寫法都是一樣的.x0dx0ax0dx0acreate or replace procere px0dx0a(v_a in number,v_b number,v_ret out number,v_temp in out number)x0dx0aisx0dx0abeginx0dx0aif(v_a > v_b) thenx0dx0av_ret := v_a;x0dx0aelsex0dx0av_ret := v_b;x0dx0aend if;x0dx0av_temp := v_temp + 1;x0dx0aend;

⑧ 如何用JAVA調用存儲過程

已儲存過程儲存在資料庫中。對已儲存過程的調用是 CallableStatement對象所含的內容。這種調用是用一種換碼語法來寫的,有兩種形式:一種形式帶結果參,另一種形式不帶結果參數。結果參數是一種輸出 (OUT) 參數,是已儲存過程的返回值。兩種形式都可帶有數量可變的輸入(IN 參數)、輸出(OUT 參數)或輸入和輸出(INOUT 參數)的參數。問號將用作參數的佔位符。 在JDBC 中調用已儲存過程的語法如下所示。注意,方括弧表示其間的內容是可選項;方括弧本身並不是語法的組成部份。{call 過程名[(?, ?, ...)]} 返回結果參數的過程的語法為:{? = call 過程名[(?, ?, ...)]} 不帶參數的已儲存過程的語法類似:{call 過程名} 通常,創建 CallableStatement 對象的人應當知道所用的 DBMS 是支持已儲存過程的,並且知道這些過程都是些什麼。然而,如果需要檢查,多種DatabaseMetaData 方法都可以提供這樣的信息。例如,如果 DBMS 支持已儲存過程的調用,則supportsStoredProceres 方法將返回 true,而getProceres 方法將返回對已儲存過程的描述。CallableStatement 繼承 Statement 的方法(它們用於處理一般的 SQL 語句),還繼承了 PreparedStatement 的方法(它們用於處理 IN 參)。 CallableStatement 中定義的所有方法都用於處理 OUT 參數或 INOUT 參數的輸出部分:注冊 OUT 參數的 JDBC 類型(一般 SQL 類型)、從這些參數中檢索結果,或者檢查所返回的值是否為 JDBC NULL。 1、創建 CallableStatement 對象 CallableStatement 對象是用 Connection 方法 prepareCall 創建的。下例創建 CallableStatement 的實例,其中含有對已儲存過程 getTestData 調用。該過程有兩個變數,但不含結果參數:CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}"); 其中?佔位符為IN、OUT還是INOUT參數,取決於已儲存過程getTestData。 2、IN和OUT參數 將IN參數傳給 CallableStatement 對象是通過 setXXX 方法完成的。該方法繼承自 PreparedStatement。所傳入參數的類型決定了所用的setXXX方法(例如,用 setFloat 來傳入 float 值等)。 如果已儲存過程返回 OUT 參數,則在執行 CallableStatement 對象以前必須先注冊每個 OUT 參數的 JDBC 類型(這是必需的,因為某些 DBMS 要求 JDBC 類型)。注冊 JDBC 類型是用 registerOutParameter 方法來完成的。語句執行完後,CallableStatement 的 getXXX 方法將取回參數值。正確的 getXXX 方法是為各參數所注冊的 JDBC 類型所對應的 Java 類型。換言之, registerOutParameter 使用的是 JDBC 類型(因此它與資料庫返回的 JDBC 類型匹配),而 getXXX 將之轉換為 Java 類型。 作為示例,下述代碼先注冊 OUT 參數,執行由 cstmt 所調用的已儲存過程,然後檢索在 OUT 參數中返回的值。方法 getByte 從第一個 OUT 參數中取出一個 Java 位元組,而 getBigDecimal 從第二個 OUT 參數中取出一個 BigDecimal 對象(小數點後面帶三位數):CallableStatement cstmt = con.prepareCall("{call getTestData(?, ?)}");
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.registerOutParameter(2, java.sql.Types.DECIMAL, 3);
cstmt.executeQuery();
byte x = cstmt.getByte(1);
java.math.BigDecimal n = cstmt.getBigDecimal(2, 3); CallableStatement 與 ResultSet 不同,它不提供用增量方式檢索大 OUT 值的特殊機制。3、INOUT參數 既支持輸入又接受輸出的參數(INOUT 參數)除了調用 registerOutParameter 方法外,還要求調用適當的 setXXX 方法(該方法是從 PreparedStatement 繼承來的)。setXXX 方法將參數值設置為輸入參數,而 registerOutParameter 方法將它的 JDBC 類型注冊為輸出參數。setXXX 方法提供一個 Java 值,而驅動程序先把這個值轉換為 JDBC 值,然後將它送到資料庫中。這種 IN 值的 JDBC 類型和提供給 registerOutParameter 方法的 JDBC 類型應該相同。然後,要檢索輸出值,就要用對應的 getXXX 方法。例如,Java 類型為byte 的參數應該使用方法 setByte 來賦輸入值。應該給registerOutParameter 提供類型為 TINYINT 的 JDBC 類型,同時應使用 getByte 來檢索輸出值。 下例假設有一個已儲存過程 reviseTotal,其唯一參數是 INOUT 參數。方法setByte 把此參數設為 25,驅動程序將把它作為 JDBC TINYINT 類型送到資料庫中。接著,registerOutParameter 將該參數注冊為 JDBC TINYINT。執行完該已儲存過程後,將返回一個新的 JDBC TINYINT 值。方法 getByte 將把這個新值作為 Java byte 類型檢索。CallableStatement cstmt = con.prepareCall("{call reviseTotal(?)}");
cstmt.setByte(1, 25);
cstmt.registerOutParameter(1, java.sql.Types.TINYINT);
cstmt.executeUpdate();
byte x = cstmt.getByte(1); 4、先檢索結果,再檢索 OUT 參數 由於某些 DBMS 的限制,為了實現最大的可移植性,建議先檢索由執行CallableStatement 對象所產生的結果,然後再用 CallableStatement.getXXX 方法來檢索 OUT 參數。如果 CallableStatement 對象返回多個 ResultSet 對象(通過調用 execute 方法),在檢索 OUT 參數前應先檢索所有的結果。這種情況下,為確保對所有的結果都進行了訪問,必須對 Statement 方法 getResultSet、getUpdateCount 和getMoreResults 進行調用,直到不再有結果為止。 檢索完所有的結果後,就可用 CallableStatement.getXXX 方法來檢索 OUT 參數中的值。 5、檢索作為OUT參數的NULL值 返回到 OUT 參數中的值可能會是JDBC NULL。當出現這種情形時,將對 JDBC NULL 值進行轉換以使 getXXX 方法所返回的值為 null、0 或 false,這取決於getXXX 方法類型。對於 ResultSet 對象,要知道0或false是否源於JDBCNULL的唯一方法,是用方法wasNull進行檢測。如果 getXXX 方法讀取的最後一個值是 JDBC NULL,則該方法返回 true,否則返回 flase。
復雜的返回值 關於存儲過程的知識,很多人好像就熟悉我們所討論的這些。如果這是存儲過程的全部功能,那麼存儲過程就不是其它遠程執行機制的替換方案了。存儲過程的功能比這強大得多。
某些DBMS允許從存儲過程中返回遊標的一個引用。JDBC並不支持這個功能,但是Oracle、PostgreSQL和DB2的JDBC驅動器都支持在ResultSet上打開到游標的指針(pointer)。
設想列出所有沒有活到退休年齡的詩人,下面是完成這個功能的存儲過程,返回一個打開的游標,同樣也使用PostgreSQL的pl/pgsql語言: create procere list_early_deaths () return refcursor as 'declare toesup refcursor;begin open toesup for SELECT poets.name, deaths.age FROM poets, deaths -- all entries in deaths are for poets. -- but the table might become generic. WHERE poets.id = deaths.mort_id AND deaths.age < 60; return toesup;end;' language 'plpgsql'; 下面是調用該存儲過程的Java方法,將結果輸出到PrintWriter:
PrintWriter: static void sendEarlyDeaths(PrintWriter out){ Connection con = null; CallableStatement toesUp = null; try { con = ConnectionPool.getConnection(); // PostgreSQL needs a transaction to do this... con. setAutoCommit(false); // Setup the call. CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }"); toesUp.registerOutParameter(1, Types.OTHER); toesUp.execute(); ResultSet rs = (ResultSet) toesUp.getObject(1); while (rs.next()) { String name = rs.getString(1); int age = rs.getInt(2); out.println(name + " was " + age + " years old."); } rs.close(); } catch (SQLException e) { // We should protect these calls. toesUp.close(); con.close(); }} 因為JDBC並不直接支持從存儲過程中返回遊標,我們使用Types.OTHER來指示存儲過程的返回類型,然後調用getObject()方法並對返回值進行強制類型轉換。
這個調用存儲過程的Java方法是mapping的一個好例子。Mapping是對一個集上的操作進行抽象的方法。不是在這個過程上返回一個集,我們可以把操作傳送進去執行。本例中,操作就是把ResultSet列印到一個輸出流。這是一個值得舉例的很常用的例子,下面是調用同一個存儲過程的另外一個方法實現: public class ProcessPoetDeaths{ public abstract void sendDeath(String name, int age);} static void mapEarlyDeaths(ProcessPoetDeaths mapper){ Connection con = null; CallableStatement toesUp = null; try { con = ConnectionPool.getConnection(); con.setAutoCommit(false); CallableStatement toesUp = connection.prepareCall("{ ? = call list_early_deaths () }"); toesUp.registerOutParameter(1, Types.OTHER); toesUp.execute(); ResultSet rs = (ResultSet) toesUp.getObject(1); while (rs.next()) { String name = rs.getString(1); int age = rs.getInt(2); mapper.sendDeath(name, age); } rs.close(); } catch (SQLException e) { // We should protect these calls. toesUp.close(); con.close(); }} 這允許在ResultSet數據上執行任意的處理,而不需要改變或者復制獲取ResultSet的方法: static void sendEarlyDeaths(final PrintWriter out){ ProcessPoetDeaths myMapper = new ProcessPoetDeaths() { public void sendDeath(String name, int age) { out.println(name + " was " + age + " years old."); } }; mapEarlyDeaths(myMapper);} 這個方法使用ProcessPoetDeaths的一個匿名實例調用mapEarlyDeaths。該實例擁有sendDeath方法的一個實現,和我們上面的例子一樣的方式把結果寫入到輸出流。當然,這個技巧並不是存儲過程特有的,但是和存儲過程中返回的ResultSet結合使用,是一個非常強大的工具。 結論存儲過程可以幫助你在代碼中分離邏輯,這基本上總是有益的。這個分離的好處有:
快速創建應用,使用和應用一起改變和改善的資料庫模式。
資料庫模式可以在以後改變而不影響Java對象,當我們完成應用後,可以重新設計更好的模式。
存儲過程通過更好的SQL嵌入使得復雜的SQL更容易理解。
編寫存儲過程比在Java中編寫嵌入的SQL擁有更好的工具--大部分編輯器都提供語法高亮!
存儲過程可以在任何SQL命令行中測試,這使得調試更加容易。 並不是所有的資料庫都支持存儲過程,但是存在許多很棒的實現,包括免費/開源的和非免費的,所以移植並不是一個問題。Oracle、PostgreSQL和DB2都有類似的存儲過程語言,並且有在線的社區很好地支持。
存儲過程工具很多,有像TOAD或TORA這樣的編輯器、調試器和IDE,提供了編寫、維護PL/SQL或pl/pgsql的強大的環境。
存儲過程確實增加了你的代碼的開銷,但是它們和大多數的應用伺服器相比,開銷小得多。

⑨ java 調用存儲過程 怎麼用

給你個我以前做的例子吧
public void proselect(){
PreparedStatement pstmt=null;
Connection conn=null;
ResultSet rs=null;
conn=com.opendb.OpenDB.conn();//這個只是建立個連接
try {
pstmt = conn.prepareCall("call sel");//調用存儲過程sel ,sel代碼為select * from test
rs=pstmt.executeQuery();
System.out.println(rs);
while(rs.next()){
System.out.print(rs.getInt(2));
System.out.println(rs.getString(1));
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

}

⑩ java代碼怎麼調用存儲過程

方法如下:importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/***LoadJDBCDriver*最基本的方法通過JDBC連接資料庫*@authorJacob**/publicclassLoadByPrimary{publicstaticvoidmain(String[]args)throwsClassNotFoundException{Stringdriver="oracle.jdbc.OracleDriver";Connectioncn=null;/***Class.forName手動載入一個類到方法區,Driver類中包含自動注冊驅動的靜態代碼塊*會自動在DriverManager中注冊驅動*/Class.forName(driver);Stringurl="jdbc:oracle:thin:@localhost:1521:ORACLE";//1521代表埠號,默認的Stringuser="用戶名";Stringpwd="密碼";try{/**Connection是介面,返回值是一個引用對象,是Oracle驅動提供實現類ojdbc7.jar*使用JDBCAPI介面,實際上是驅動實現類*/cn=DriverManager.getConnection(url,user,pwd);Statementstmt=cn.createStatement();Stringsql="SELECT*FROMstu_empWHEREdeptno=10";ResultSetrs=stmt.executeQuery(sql);while(rs.next()){System.out.println(rs.getInt("empno")+""+rs.getString("ename")+""+rs.getString("job"));}rs.close();stmt.close();}catch(SQLExceptione){e.printStackTrace();}finally{try{if(cn!=null){cn.close();}}catch(SQLExceptione2){e2.printStackTrace();}}}}這是通過preparedstatement實現更新數據,這里我把連接資料庫的方法進行了封裝,每次直接調用了。publicstaticvoidmain(String[]args){PreparedStatementDemopsd=newPreparedStatementDemo();psd.updateSalary("JACOB",3000);psd.selectSalary("JACOB");}publicvoipdateSalary(Stringename,doublesal){Stringsql="Updatestu_empsetsal=?Whereename=?";Connectioncn=null;PreparedStatementps=null;try{cn=DBPUtil.getConnection();ps=cn.prepareStatement(sql);ps.setDouble(1,sal);ps.setString(2,ename);intnum=ps.executeUpdate();System.out.println("提示:總共有"+num+"條數據已經更新!");}catch(SQLExceptione){e.printStackTrace();}finally{DBUtil.stmtClose(ps);DBUtil.connClose(cn);}}publicvoidselectSalary(Stringname){Stringsql="Select*Fromstu_empWhereename=?";Connectioncn=null;PreparedStatementps=null;ResultSetrs=null;try{cn=DBPUtil.getConnection();ps=cn.prepareStatement(sql);ps.setString(1,name);rs=ps.executeQuery();while(rs.next()){System.out.println(rs.getString("ename")+"的工資是:"+rs.getInt("sal"));}}catch(SQLExceptione){e.printStackTrace();}finally{DBUtil.stmtClose(ps);DBUtil.rsClose(rs);DBUtil.connClose(cn);}}}

熱點內容
4399賬號綁定qq怎麼改密碼 發布:2025-09-24 01:52:15 瀏覽:743
資料庫access2010教程 發布:2025-09-24 01:42:13 瀏覽:901
臨時存儲器 發布:2025-09-24 01:38:33 瀏覽:710
跟蹤測演算法 發布:2025-09-24 01:37:42 瀏覽:207
如何編譯內核模塊 發布:2025-09-24 01:14:47 瀏覽:754
王者榮耀官方伺服器地址 發布:2025-09-24 00:47:29 瀏覽:192
gif在線壓縮免費 發布:2025-09-24 00:41:13 瀏覽:947
tcl腳本if 發布:2025-09-24 00:26:59 瀏覽:709
蘋果手機怎麼連個人安卓手機熱點 發布:2025-09-24 00:20:46 瀏覽:133
虛擬專用賬號密碼在哪裡注冊 發布:2025-09-23 23:57:20 瀏覽:181