真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

存儲過程和java代碼 存儲過程和java代碼的關(guān)系

Java數(shù)據(jù)庫程序中的存儲過程設(shè)計

本文闡述了怎么使用DBMS存儲過程 闡述了使用存儲過程的基本的和高級特性 比如返回ResultSet 本文假設(shè)你對DBMS和JDBC已經(jīng)非常熟悉 也假設(shè)你能夠毫無障礙地閱讀其它語言寫成的代碼(即不是Java的語言) 但是 并不要求你有任何存儲過程的編程經(jīng)歷

目前創(chuàng)新互聯(lián)已為近千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、網(wǎng)站托管運(yùn)營、企業(yè)網(wǎng)站設(shè)計、麻山網(wǎng)站維護(hù)等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

存儲過程是指保存在數(shù)據(jù)庫并在數(shù)據(jù)庫端執(zhí)行的程序 你可以使用特殊的語法在Java類中調(diào)用存儲過程 在調(diào)用時 存儲過程的名稱及指定的參數(shù)通過JDBC連接發(fā)送給DBMS 執(zhí)行存儲過程并通過連接(如果有)返回結(jié)果

使用存儲過程擁有和使用基于EJB或CORBA這樣的應(yīng)用服務(wù)器一樣的好處 區(qū)別是存儲過程可以從很多流行的DBMS中免費(fèi)使用 而應(yīng)用服務(wù)器大都非常昂貴 這并不只是許可證費(fèi)用的問題 使用應(yīng)用服務(wù)器所需要花費(fèi)的管理 編寫代碼的費(fèi)用 以及客戶程序所增加的復(fù)雜性 都可以通過DBMS中的存儲過程所整個地替代

你可以使用Java Python Perl或C編寫存儲過程 但是通常使用你的DBMS所指定的特定語言 Oracle使用PL/SQL PostgreSQL使用pl/pgsql DB 使用Procedural SQL 這些語言都非常相似 在它們之間移植存儲過程并不比在Sun的EJB規(guī)范不同實現(xiàn)版本之間移植Session Bean困難 并且 存儲過程是為嵌入SQL所設(shè)計 這使得它們比Java或C等語言更加友好地方式表達(dá)數(shù)據(jù)庫的機(jī)制

因為存儲過程運(yùn)行在DBMS自身 這可以幫助減少應(yīng)用程序中的等待時間 不是在Java代碼中執(zhí)行 個或 個SQL語句 而只需要在服務(wù)器端執(zhí)行 個存儲過程 網(wǎng)絡(luò)上的數(shù)據(jù)往返次數(shù)的減少可以戲劇性地優(yōu)化性能

使用存儲過程

簡單的老的JDBC通過CallableStatement類支持存儲過程的調(diào)用 該類實際上是PreparedStatement的一個子類 假設(shè)我們有一個poets數(shù)據(jù)庫 數(shù)據(jù)庫中有一個設(shè)置詩人逝世年齡的存儲過程 下面是對老酒鬼Dylan Thomas(old soak Dylan Thomas 不指定是否有關(guān)典故 文化 請批評指正 譯注)進(jìn)行調(diào)用的詳細(xì)代碼

try{ int age = ; String poetName = dylan thomas ; CallableStatement proc = connection prepareCall( { call set_death_age(? ?) } ); proc setString( poetName); proc setInt( age); cs execute();}catch (SQLException e){ // }

傳給prepareCall方法的字串是存儲過程調(diào)用的書寫規(guī)范 它指定了存儲過程的名稱 ?代表了你需要指定的參數(shù)

和JDBC集成是存儲過程的一個很大的便利 為了從應(yīng)用中調(diào)用存儲過程 不需要存根(stub)類或者配置文件 除了你的DBMS的JDBC驅(qū)動程序外什么也不需要

當(dāng)這段代碼執(zhí)行時 數(shù)據(jù)庫的存儲過程就被調(diào)用 我們沒有去獲取結(jié)果 因為該存儲過程并不返回結(jié)果 執(zhí)行成功或失敗將通過例外得知 失敗可能意味著調(diào)用存儲過程時的失?。ū热缣峁┑囊粋€參數(shù)的類型不正確) 或者一個應(yīng)用程序的失敗(比如拋出一個例外指示在poets數(shù)據(jù)庫中并不存在 Dylan Thomas )

結(jié)合SQL操作與存儲過程

映射Java對象到SQL表中的行相當(dāng)簡單 但是通常需要執(zhí)行幾個SQL語句 可能是一個SELECT查找ID 然后一個INSERT插入指定ID的數(shù)據(jù) 在高度規(guī)格化(符合更高的范式 譯注)的數(shù)據(jù)庫模式中 可能需要多個表的更新 因此需要更多的語句 Java代碼會很快地膨脹 每一個語句的網(wǎng)絡(luò)開銷也迅速增加

將這些SQL語句轉(zhuǎn)移到一個存儲過程中將大大簡化代碼 僅涉及一次網(wǎng)絡(luò)調(diào)用 所有關(guān)聯(lián)的SQL操作都可以在數(shù)據(jù)庫內(nèi)部發(fā)生 并且 存儲過程語言 例如PL/SQL 允許使用SQL語法 這比Java代碼更加自然 下面是我們早期的存儲過程 使用Oracle的PL/SQL語言編寫

create procedure set_death_age(poet VARCHAR poet_age NUMBER)poet_id NUMBER;beginSELECT id INTO poet_id FROM poets WHERE name = poet;INSERT INTO deaths (mort_id age) VALUES (poet_id poet_age);end set_death_age;

很獨特?不 我打賭你一定期待看到一個poets表上的UPDATE 這也暗示了使用存儲過程實現(xiàn)是多么容易的一件事情 set_death_age幾乎可以肯定是一個很爛的實現(xiàn) 我們應(yīng)該在poets表中添加一列來存儲逝世年齡 Java代碼中并不關(guān)心數(shù)據(jù)庫模式是怎么實現(xiàn)的 因為它僅調(diào)用存儲過程 我們以后可以改變數(shù)據(jù)庫模式以提高性能 但是我們不必修改我們代碼

下面是調(diào)用上面存儲過程的Java代碼

public static void setDeathAge(Poet dyingBard int age)throws SQLException{ Connection con = null; CallableStatement proc = null;

try {con = connectionPool getConnection();proc = con prepareCall( { call set_death_age(? ?) } );proc setString( dyingBard getName());proc setInt( age);proc execute(); } finally {try{ proc close();}catch (SQLException e) {}con close(); }}

為了確保可維護(hù)性 建議使用像這兒這樣的static方法 這也使得調(diào)用存儲過程的代碼集中在一個簡單的模版代碼中 如果你用到許多存儲過程 就會發(fā)現(xiàn)僅需要拷貝 粘貼就可以創(chuàng)建新的方法 因為代碼的模版化 甚至也可以通過腳本自動生產(chǎn)調(diào)用存儲過程的代碼

Functions

存儲過程可以有返回值 所以CallableStatement類有類似getResultSet這樣的方法來獲取返回值 當(dāng)存儲過程返回一個值時 你必須使用registerOutParameter方法告訴JDBC驅(qū)動器該值的SQL類型是什么 你也必須調(diào)整存儲過程調(diào)用來指示該過程返回一個值

下面接著上面的例子 這次我們查詢Dylan Thomas逝世時的年齡 這次的存儲過程使用PostgreSQL的pl/pgsql

create function snuffed_it_when (VARCHAR) returns integer declarepoet_id NUMBER;poet_age NUMBER;begin first get the id associated with the poet SELECT id INTO poet_id FROM poets WHERE name = $ ; get and return the age SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id;return age;end; language pl/pgsql ;

另外 注意pl/pgsql參數(shù)名通過Unix和DOS腳本的$n語法引用 同時 也注意嵌入的注釋 這是和Java代碼相比的另一個優(yōu)越性 在Java中寫這樣的注釋當(dāng)然是可以的 但是看起來很凌亂 并且和SQL語句脫節(jié) 必須嵌入到Java String中

下面是調(diào)用這個存儲過程的Java代碼

connection setAutoCommit(false);CallableStatement proc =connection prepareCall( { ? = call snuffed_it_when(?) } );proc registerOutParameter( Types INTEGER);proc setString( poetName);cs execute();int age = proc getInt( );

如果指定了錯誤的返回值類型會怎樣?那么 當(dāng)調(diào)用存儲過程時將拋出一個RuntimeException 正如你在ResultSet操作中使用了一個錯誤的類型所碰到的一樣

復(fù)雜的返回值

關(guān)于存儲過程的知識 很多人好像就熟悉我們所討論的這些 如果這是存儲過程的全部功能 那么存儲過程就不是其它遠(yuǎn)程執(zhí)行機(jī)制的替換方案了 存儲過程的功能比這強(qiáng)大得多

當(dāng)你執(zhí)行一個SQL查詢時 DBMS創(chuàng)建一個叫做cursor(游標(biāo))的數(shù)據(jù)庫對象 用于在返回結(jié)果中迭代每一行 ResultSet是當(dāng)前時間點的游標(biāo)的一個表示 這就是為什么沒有緩存或者特定數(shù)據(jù)庫的支持 你只能在ResultSet中向前移動

某些DBMS允許從存儲過程中返回游標(biāo)的一個引用 JDBC并不支持這個功能 但是Oracle PostgreSQL和DB 的JDBC驅(qū)動器都支持在ResultSet上打開到游標(biāo)的指針(pointer)

設(shè)想列出所有沒有活到退休年齡的詩人 下面是完成這個功能的存儲過程 返回一個打開的游標(biāo) 同樣也使用PostgreSQL的pl/pgsql語言

create procedure list_early_deaths () return refcursor as declaretoesup refcursor;beginopen toesup forSELECT poets name deaths ageFROM poets deaths all entries in deaths are for poets but the table might bee generic WHERE poets id = deaths mort_idAND deaths age ;return toesup;end; language plpgsql ;

下面是調(diào)用該存儲過程的Java方法 將結(jié)果輸出到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( Types OTHER);getResults execute();

ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); out println(name + was + age + years old );}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}

因為JDBC并不直接支持從存儲過程中返回游標(biāo) 我們使用Types OTHER來指示存儲過程的返回類型 然后調(diào)用getObject()方法并對返回值進(jìn)行強(qiáng)制類型轉(zhuǎn)換

這個調(diào)用存儲過程的Java方法是mapping的一個好例子 Mapping是對一個集上的操作進(jìn)行抽象的方法 不是在這個過程上返回一個集 我們可以把操作傳送進(jìn)去執(zhí)行 本例中 操作就是把ResultSet打印到一個輸出流 這是一個值得舉例的很常用的例子 下面是調(diào)用同一個存儲過程的另外一個方法實現(xiàn)

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( Types OTHER);getResults execute();

ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); mapper sendDeath(name age);}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}

這允許在ResultSet數(shù)據(jù)上執(zhí)行任意的處理 而不需要改變或者復(fù)制獲取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的一個匿名實例調(diào)用mapEarlyDeaths 該實例擁有sendDeath方法的一個實現(xiàn) 和我們上面的例子一樣的方式把結(jié)果寫入到輸出流 當(dāng)然 這個技巧并不是存儲過程特有的 但是和存儲過程中返回的ResultSet結(jié)合使用 是一個非常強(qiáng)大的工具

結(jié)論

存儲過程可以幫助你在代碼中分離邏輯 這基本上總是有益的 這個分離的好處有

快速創(chuàng)建應(yīng)用 使用和應(yīng)用一起改變和改善的數(shù)據(jù)庫模式

數(shù)據(jù)庫模式可以在以后改變而不影響Java對象 當(dāng)我們完成應(yīng)用后 可以重新設(shè)計更好的模式

存儲過程通過更好的SQL嵌入使得復(fù)雜的SQL更容易理解

編寫存儲過程比在Java中編寫嵌入的SQL擁有更好的工具——大部分編輯器都提供語法高亮!

存儲過程可以在任何SQL命令行中測試 這使得調(diào)試更加容易

并不是所有的數(shù)據(jù)庫都支持存儲過程 但是存在許多很棒的實現(xiàn) 包括免費(fèi)/開源的和非免費(fèi)的 所以移植并不是一個問題 Oracle PostgreSQL和DB 都有類似的存儲過程語言 并且有在線的社區(qū)很好地支持

存儲過程工具很多 有像TOAD或TORA這樣的編輯器 調(diào)試器和IDE 提供了編寫 維護(hù)PL/SQL或pl/pgsql的強(qiáng)大的環(huán)境

lishixinzhi/Article/program/Java/hx/201311/25906

如何讓java代碼 sqrvel 存儲過程

我給你一個訪問存儲過程的java程序吧

import java.sql.*;

public class ProcedureTest {

/**

* java調(diào)用存儲過程

*/

public static void main(String[] args)

{

// TODO 自動生成方法存根

Connection sqlCon = null; //數(shù)據(jù)庫連接對象

CallableStatement sqlStmt=null; //可調(diào)用語句對象

String strCon; //數(shù)據(jù)庫連接字符串

String strSQL; //SQL語句

//裝載JDBC-ODBC驅(qū)動程序

try

{

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

} catch (ClassNotFoundException e) {

// TODO 自動生成 catch 塊

e.printStackTrace();

}

//設(shè)置數(shù)據(jù)庫連接字符串

strCon="jdbc:odbc:MyProcedure";

//連接數(shù)據(jù)庫

try

{

sqlCon=DriverManager.getConnection(strCon);

} catch (SQLException e) {

// TODO 自動生成 catch 塊

e.printStackTrace();

}

/**調(diào)用存儲過程

*

*/

//準(zhǔn)備SQL語句

strSQL="{call 登陸(?,?,?)}";

//準(zhǔn)備可調(diào)用語句對象

try

{

sqlStmt=sqlCon.prepareCall(strSQL);

//設(shè)置輸入?yún)?shù)

sqlStmt.setString(1,"Mary");

sqlStmt.setString(2,"hello");

//登記出參

String msg=null;

sqlStmt.registerOutParameter(3, Types.VARCHAR);

sqlStmt.execute();

msg=sqlStmt.getString(3);

System.out.println(msg);

} catch (SQLException e) {

// TODO 自動生成 catch 塊

e.printStackTrace();

}

//關(guān)閉數(shù)據(jù)庫

try

{

//關(guān)閉可調(diào)用語句對象

sqlStmt.close();

//關(guān)閉數(shù)據(jù)庫連接對象

sqlCon.close();

} catch (SQLException e) {

// TODO 自動生成 catch 塊

e.printStackTrace();

}

}

}

其中存儲過程“登陸”是這樣寫的

CREATE PROCEDURE 登陸

@login_name VARCHAR(255),

@password VARCHAR(255),

@msg VARCHAR(50) OUTPUT

AS

BEGIN

IF EXISTS( SELECT * FROM user_table WHERE login_name=@login_name )

BEGIN

IF EXISTS( SELECT * FROM user_table WHERE login_name=@login_name AND password=@password )

SET @msg='用戶名與密碼都正確,成功登陸!'

ELSE

SET @msg='密碼不正確,請重新輸入!'

END

ELSE

SET @msg='用戶名不正確,請重新輸入!'

END

java代碼怎么調(diào)用存儲過程

方法如下:importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/***LoadJDBCDriver*最基本的方法通過JDBC連接數(shù)據(jù)庫*@authorJacob**/publicclassLoadByPrimary{publicstaticvoidmain(String[]args)throwsClassNotFoundException{Stringdriver="oracle.jdbc.OracleDriver";Connectioncn=null;/***Class.forName手動加載一個類到方法區(qū),Driver類中包含自動注冊驅(qū)動的靜態(tài)代碼塊*會自動在DriverManager中注冊驅(qū)動*/Class.forName(driver);Stringurl="jdbc:oracle:thin:@localhost:1521:ORACLE";//1521代表端口號,默認(rèn)的Stringuser="用戶名";Stringpwd="密碼";try{/**Connection是接口,返回值是一個引用對象,是Oracle驅(qū)動提供實現(xiàn)類ojdbc7.jar*使用JDBCAPI接口,實際上是驅(qū)動實現(xiàn)類*/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實現(xiàn)更新數(shù)據(jù),這里我把連接數(shù)據(jù)庫的方法進(jìn)行了封裝,每次直接調(diào)用了。publicstaticvoidmain(String[]args){PreparedStatementDemopsd=newPreparedStatementDemo();psd.updateSalary("JACOB",3000);psd.selectSalary("JACOB");}publicvoidupdateSalary(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+"條數(shù)據(jù)已經(jīng)更新!");}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);}}}

java編程中怎樣調(diào)用存儲過程

JDBC調(diào)用存儲過程: CallableStatement

在Java里面調(diào)用存儲過程,寫法那是相當(dāng)?shù)墓潭ǎ?/p>

Class.forName(....

Connection conn = DriverManager.getConnection(....

/**

*p是要調(diào)用的存儲過程的名字,存儲過程的4個參數(shù),用4個?號占位符代替

*其余地方寫法固定

*/

CallableStatement cstmt = conn.prepareCall("{call p(?,?,?,?)}");

/**

*告訴JDBC,這些個參數(shù),哪些是輸出參數(shù),輸出參數(shù)的類型用java.sql.Types來指定

*下面的意思是,第3個?和第4個?是輸出參數(shù),類型是INTEGER的

*Types后面具體寫什么類型,得看你的存儲過程參數(shù)怎么定義的

*/

cstmt.registerOutParameter(3, Types.INTEGER);

cstmt.registerOutParameter(4, Types.INTEGER);

/**

*在我這里第1個?和第2個?是輸入?yún)?shù),第3個是輸出參數(shù),第4個既輸入又輸出

*下面是設(shè)置他們的值,第一個設(shè)為3,第二個設(shè)為4,第4個設(shè)置為5

*沒設(shè)第3個,因為它是輸出參數(shù)

*/

cstmt.setInt(1, 3);

cstmt.setInt(2, 4);

cstmt.setInt(4, 5);

//執(zhí)行

cstmt.execute();

//把第3個參數(shù)的值當(dāng)成int類型拿出來

int three = cstmt.getInt(3);

System.out.println(three);

//把第4個參數(shù)的值當(dāng)成int類型拿出來

int four = cstmt.getInt(4);

System.out.println(four);

//用完別忘給人家關(guān)了,后開的先關(guān)

cstmt.close();

conn.close();

JDBC調(diào)用存儲過程,掌握這一個程序足夠了.

以下是上面程序使用的存儲過程的代碼,我用的是Oracle數(shù)據(jù)庫,不過不論是什么數(shù)據(jù)庫,對于你的程序,JDBC這一端寫法都是一樣的.

create or replace procedure 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;

oracle存儲過程怎么和java代碼

2、什么時候需要用存儲過程

如果服務(wù)器定義了存儲過程,應(yīng)當(dāng)根據(jù)需要決定是否要用存儲過程。存儲過程通常是一些經(jīng)常要執(zhí)行的任務(wù),這些任務(wù)往往是針對大量的記錄而進(jìn)行的。在服務(wù)器上執(zhí)行存儲過程,可以改善應(yīng)用程序的性能。這是因為:

.服務(wù)器往往具有強(qiáng)大的計算能力和速度。

.避免把大量的數(shù)據(jù)下載到客戶端,減少網(wǎng)絡(luò)上的傳輸量。

例如,假設(shè)一個應(yīng)用程序需要計算一個數(shù)據(jù),這個數(shù)據(jù)需要涉及到許多記錄。如果不使用存儲過程的話,把這些數(shù)據(jù)下載到客戶端,導(dǎo)致網(wǎng)絡(luò)上的流量劇增。

不僅如此,客戶端可能是一臺老掉牙的計算機(jī),它的運(yùn)算速度很慢。而改用存儲過程后,服務(wù)器會很快地把數(shù)據(jù)計算出來,并且只需傳遞一個數(shù)據(jù)給客戶端,其效率之高是非常明顯的。

3、存儲過程的參數(shù)

java如何調(diào)用存儲過程 代碼如下,最好能解釋下相關(guān)函數(shù)的作用,不勝感激

這是我以前的學(xué)習(xí)筆記,LZ湊合著看看吧,應(yīng)該能看懂一些吧

===================================================

55 java跟oracle 調(diào)用(存儲過程,函數(shù)等)

55.1 Java調(diào)用無參的函數(shù)

1:函數(shù)為:

create or replace function MyF1 return varchar2 is

Result varchar2(20);

begin

dbms_output.put_line('now in My F1');

Result := 'Now MyF1 return';

return(Result);

end MyF1;

2:Java程序

/**

* 演示調(diào)用有一個沒有參數(shù)的函數(shù)

* @throws Exception

*/

private static void t1() throws Exception {

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "test", "test");

try {

CallableStatement stmt = conn

.prepareCall("{?=call MyF1()}");

stmt.registerOutParameter(1, Types.VARCHAR);

stmt.execute();

System.out.println(stmt.getString(1));

} finally {

conn.close();

}

}

55.2 Java調(diào)用無參但有返回值的存儲過程

1:存儲過程

create or replace procedure MyP1(str out Varchar2) is

begin

dbms_output.put_line('Hello Procedure.');

str :='Haha,Hello Procedure';

end MyP1;

2:程序

/**

* 如何調(diào)用無參但有返回值的存儲過程 測試的存儲過程

* @throws Exception

*/

private static void t2() throws Exception {

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "test", "test");

try {

CallableStatement stmt = conn.prepareCall("{call MyP1(?)}");

// 注意,這里的stmt.getInt(1)中的數(shù)值1并非任意的,而是和存儲過程中的out列對應(yīng)的,

// 如果out是在第一個位置,那就是 stmt.getInt(1),如果是第三個位置,就是getInt.getInt(3),

// 當(dāng)然也可以同時有多個返回值,那就是再多加幾個out 參數(shù)了。

stmt.registerOutParameter(1, Types.VARCHAR);

stmt.execute();

System.out.println(stmt.getString(1));

} finally {

conn.close();

}

}

55.3 Java調(diào)用有參的(傳入)函數(shù)

1:函數(shù)

create or replace function MyF2(a number,b varchar2) return varchar2 is

Result varchar2(50);

begin

dbms_output.put_line('a==='||a||',b=='||b);

Result := a||b;

return(Result);

end MyF2;

2:程序

/**

* 調(diào)用有參的函數(shù)

* @throws Exception

*/

private static void t3() throws Exception {

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "test", "test");

try {

CallableStatement stmt = conn

.prepareCall("{?=call MyF2(?,?)}");

stmt.setInt(2, 15);

stmt.setString(3, "HelloF2");

stmt.registerOutParameter(1, Types.VARCHAR);

stmt.execute();

System.out.println(stmt.getString(1));

} finally {

conn.close();

}

}

55.4 Java調(diào)用有參的(傳入傳出)存儲過程

1:存儲過程

create or replace procedure MyP2(a in number,b in varchar2,c out varchar2) is

begin

dbms_output.put_line('a=='||a||',b=='||b);

c := 'ret=='||a||',b=='||b;

end MyP2;

2:程序

/**

* 調(diào)用有參數(shù)和返回值的存儲過程

* @throws Exception

*/

private static void t4() throws Exception {

Class.forName("oracle.jdbc.driver.OracleDriver");

Connection conn = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "test", "test");

try {

CallableStatement stmt = conn.prepareCall("{call MyP2(?,?,?)}");

stmt.setInt(1, 5);

stmt.setString(2, "測試");

stmt.registerOutParameter(3, Types.VARCHAR);

stmt.execute();

System.out.println(stmt.getString(3));

} finally {

conn.close();

}

}

55.5 Java向存儲過程傳入傳出對象的數(shù)組

1:在數(shù)據(jù)中創(chuàng)建對象

create or replace type UserModel as object(

uuid varchar2(20),

name varchar2(20)

);

2:在數(shù)據(jù)庫中建立對象的集合類型

create or replace type userCol as table of UserModel;

create or replace type retUserCol as table of UserModel;

3:在數(shù)據(jù)庫中建立包

包頭:

create or replace package MyTestPackage is

TYPE dbRs IS REF CURSOR;

procedure MyP3(a1 in userCol,a2 out dbRs);

end MyTestPackage;

包體:

create or replace package body MyTestPackage is

procedure MyP3(a1 in userCol,a2 out dbRs) as

umCol retUserCol := retUserCol();

begin

for i in 1.. a1.count loop

insert into tbl_test values (a1(i).uuid,a1(i).name);

end loop;

commit;

umCol.Extend;

umCol(1):=UserModel('retUuid11','retName11');

umCol.Extend;

umCol(2):=UserModel('retUuid22','retName22');

open a2 for select * from table(cast(umCol as retUserCol));

end;

begin

null;

end MyTestPackage;

4:程序:

/**

* 測試向pl/sql傳入對象集合,從pl/sql返回任意的對象的集合

* @param list

* @throws Exception

*/

private static void t5(List list) throws Exception {

CallableStatement stmt = null;

Connection con = null;

try {

Class.forName("oracle.jdbc.driver.OracleDriver");

con = DriverManager.getConnection(

"jdbc:oracle:thin:@127.0.0.1:1521:orcl", "test", "test");

if (con != null) {

ARRAY aArray = getArray(con, "USERMODEL", "USERCOL", list);//該函數(shù)調(diào)用的第二三個參數(shù)必須大寫

stmt = con.prepareCall("{call MyTestPackage.MyP3(?,?)}");

((OracleCallableStatement) stmt).setARRAY(1, aArray);

stmt.registerOutParameter(2, OracleTypes.CURSOR);

stmt.execute();

ResultSet rs=(ResultSet)stmt.getObject(2);

while(rs.next()){

String uuid = rs.getString("uuid");

String name = rs.getString("name");

System.out.println("the uuid="+uuid+",name="+name);

}

}

} catch (Exception e) {

e.printStackTrace();

} finally {

try {

con.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

private static ARRAY getArray(Connection con, String OracleObj, String Oraclelist,

List objlist) throws Exception {

ARRAY list = null;

if (objlist != null objlist.size() 0) {

StructDescriptor structdesc = new StructDescriptor(OracleObj, con);

STRUCT[] structs = new STRUCT[objlist.size()];

Object[] result = new Object[0];

for (int i = 0; i objlist.size(); i++) {

result = new Object[2];//數(shù)組大小應(yīng)和你定義的數(shù)據(jù)庫對象(UserModel)的屬性的個數(shù)

result[0] = ((UserModel)(objlist.get(i))).getUuid(); //將list中元素的數(shù)據(jù)傳入result數(shù)組

result[1] = ((UserModel)(objlist.get(i))).getName(); //

structs[i] = new STRUCT(structdesc, con, result);

}

ArrayDescriptor desc = ArrayDescriptor.createDescriptor(Oraclelist,

con);

list = new ARRAY(desc, con, structs);

}

return list;

}

如果使用Tomcat的DBCP的連接池,需要把連接進(jìn)行轉(zhuǎn)換

public Connection getNativeConnection(Connection con) throws SQLException {

if (con instanceof DelegatingConnection) {

Connection nativeCon = ((DelegatingConnection) con).getInnermostDelegate();

return (nativeCon != null ? nativeCon : con.getMetaData().getConnection());

}

return con;

}


網(wǎng)頁標(biāo)題:存儲過程和java代碼 存儲過程和java代碼的關(guān)系
文章位置:http://weahome.cn/article/hghjes.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部