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

存儲過程調用java

發布時間: 2025-07-25 04:07:17

1. 如何執行存儲過程

執行存儲過程的方法如下

  1. 使用PL/sql工具

    • 登錄PL/SQL工具:首先,打開PL/SQL工具,並輸入登錄名和密碼進行登錄。
    • 進入命令窗口:登錄成功後,進入PL/SQL的命令窗口。
    • 設置伺服器輸出:在命令窗口中輸入set serveroutput on;並按回車鍵,以確保能夠查看存儲過程的輸出結果。
    • 執行存儲過程
      • 使用execute命令:輸入execute 存儲過程名;並執行,即可調用存儲過程。
      • 使用begin...end塊:如果需要更復雜的控制,可以使用begin 存儲過程名; end;的形式來執行存儲過程。
  2. 在其他編程語言中調用

    • java示例:在Java等編程語言中,可以通過JDBC來調用存儲過程。這通常涉及到建立資料庫連接、准備存儲過程調用語句、設置參數、執行存儲過程以及處理結果集。

注意:具體執行存儲過程的語法和步驟可能因資料庫管理系統和所使用的工具或編程語言而有所不同。上述步驟以PL/SQL工具為例,其他環境可能需要調整。

2. Java如何實現對存儲過程的調用

import java.sql.*;
public class ProcereTest
{
public static void main(String args[]) throws Exception
{
//載入驅動
DriverManager.registerDriver(new sun.jdbc.odbc.JdbcOdbcDriver());
//獲得連接
Connection conn=DriverManager.getConnection("jdbc:odbc:mydata","sa","");

//創建存儲過程的對象
CallableStatement c=conn.prepareCall("{call getsum(?,?)}");

//給存儲過程的第一個參數設置值
c.setInt(1,100);

//注冊存儲過程的第二個參數
c.registerOutParameter(2,java.sql.Types.INTEGER);

//執行存儲過程
c.execute();

//得到存儲過程的輸出參數值
System.out.println (c.getInt(2));
conn.close();

}
}

3. 求java調用oracle存儲過程

一:無返回值的存儲過程
存儲過程為:
CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2) AS
BEGIN
INSERT INTO HYQ.B_ID (I_ID,I_NAME) VALUES (PARA1, PARA2);
END TESTA;
然後呢,在java里調用時就用下面的代碼:
package com.hyq.src;
import java.sql.*;
import java.sql.ResultSet;
public class TestProcereOne {
public TestProcereOne() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521: hyq ";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
CallableStatement cstmt = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, " hyq", " hyq ");
CallableStatement proc = null;
proc = conn.prepareCall("{ call HYQ.TESTA(?,?) }");
proc.setString(1, "100");
proc.setString(2, "TestOne");
proc.execute();
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}
當然了,這就先要求要建張表TESTTB,裡面兩個欄位(I_ID,I_NAME)。
二:有返回值的存儲過程(非列表)
存儲過程為:
CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS
BEGIN
SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;
END TESTB;
在java里調用時就用下面的代碼:
package com.hyq.src;
public class TestProcereTWO {
public TestProcereTWO() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl ="jdbc:oracle:thin:@127.0.0.1:1521:hyq";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, " hyq", " hyq ");
CallableStatement proc = null;
proc = conn.prepareCall("{ call HYQ.TESTB(?,?) }");
proc.setString(1, "100");
proc.registerOutParameter(2, Types.VARCHAR);
proc.execute();
String testPrint = proc.getString(2);
System.out.println("=testPrint=is="+testPrint);
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}
}
注意,這里的proc.getString(2)中的數值2並非任意的,而是和存儲過程中的out列對應的,如果out是在第一個位置,那就是proc.getString(1),如果是第三個位置,就是proc.getString(3),當然也可以同時有多個返回值,那就是再多加幾個out參數了。
三:返回列表
由於oracle存儲過程沒有返回值,它的所有返回值都是通過out參數來替代的,列表同樣也不例外,但由於是集合,所以不能用一般的參數,必須要用pagkage了.所以要分兩部分,
1, 建一個程序包。如下:
CREATE OR REPLACE PACKAGE TESTPACKAGE AS
TYPE Test_CURSOR IS REF CURSOR;
end TESTPACKAGE;
2,建立存儲過程,存儲過程為:
CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS
BEGIN
OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;
END TESTC;
可以看到,它是把游標(可以理解為一個指針),作為一個out 參數來返回值的。
在java里調用時就用下面的代碼:
package com.hyq.src;
import java.sql.*;
import java.io.OutputStream;
import java.io.Writer;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import oracle.jdbc.driver.*;
public class TestProcereTHREE {
public TestProcereTHREE() {
}
public static void main(String[] args ){
String driver = "oracle.jdbc.driver.OracleDriver";
String strUrl ="jdbc:oracle:thin:@127.0.0.1:1521:hyq";
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, "hyq","hyq");
CallableStatement proc = null;
proc = conn.prepareCall("{ call hyq.testc(?) }");
proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
rs = (ResultSet)proc.getObject(1);
while(rs.next())
{
System.out.println("" + rs.getString(1) +""+rs.getString(2)+"");
}
}
catch (SQLException ex2) {
ex2.printStackTrace();
}
catch (Exception ex2) {
ex2.printStackTrace();
}
finally{
try {
if(rs != null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch (SQLException ex1) {
}
}
}
}

4. 在JAVA中怎麼調用帶參數的存儲過程啊

JDBC調用存儲過程是Java中執行資料庫存儲過程的一種方式,關鍵在於使用CallableStatement對象。首先,需要正確配置資料庫驅動,然後通過DriverManager.getConnection方法獲取資料庫連接。

例如,調用存儲過程p,它有四個參數,可以使用問號佔位符表示這些參數:

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

接下來,需要注冊輸出參數。這里,第三個和第四個問號被視為輸出參數,並指明它們的數據類型為INTEGER:

cstmt.registerOutParameter(3, Types.INTEGER);

cstmt.registerOutParameter(4, Types.INTEGER);

對於輸入參數,可以使用setInt方法設置值。比如,第一個和第二個問號作為輸入參數,第三個既作為輸入又作為輸出參數,第四個作為輸入參數:

cstmt.setInt(1, 3);
cstmt.setInt(2, 4);
cstmt.setInt(4, 5);

然後,調用execute方法執行存儲過程:

cstmt.execute();

最後,獲取輸出參數的值,如:

int three = cstmt.getInt(3);
System.out.println(three);
int four = cstmt.getInt(4);
System.out.println(four);

執行完畢後,記得關閉CallableStatement和Connection對象:

cstmt.close();
conn.close();

以上步驟是Java中調用帶參數的存儲過程的標准流程,適用於多種資料庫系統,特別是Oracle。下面給出一個Oracle資料庫中使用的存儲過程代碼示例:

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;

這段代碼定義了一個存儲過程,包含輸入參數v_a和v_b,輸出參數v_ret,以及一個輸入輸出參數v_temp。

5. 執行存儲過程有多少種方法java

Java執行存儲過程的方法:

簡單的老的JDBC通過CallableStatement類支持存儲過程的調用。該類實際上是PreparedStatement的一個子類。假設有一個poets資料庫。資料庫中有一個設置詩人逝世年齡的存儲過程。下面是對老酒鬼Dylan Thomas(old soak Dylan Thomas,不指定是否有關典故、文化,請批評指正。譯注)進行調用的詳細代碼:

try{
intage=39;
StringpoetName="dylanthomas";
CallableStatementproc=connection.prepareCall("{callset_death_age(?,?)}");
proc.setString(1,poetName);
proc.setInt(2,age);
cs.execute();
}catch(SQLExceptione){//....}

傳給prepareCall方法的字串是存儲過程調用的書寫規范。它指定了存儲過程的名稱,?代表了需要指定的參數。
和JDBC集成是存儲過程的一個很大的便利:為了從應用中調用存儲過程,不需要存根(stub)類或者配置文件,除了你的DBMS的JDBC驅動程序外什麼也不需要。
當這段代碼執行時,資料庫的存儲過程就被調用。我們沒有去獲取結果,因為該存儲過程並不返回結果。執行成功或失敗將通過例外得知。失敗可能意味著調用存儲過程時的失敗(比如提供的一個參數的類型不正確),或者一個應用程序的失敗(比如拋出一個例外指示在poets資料庫中並不存在「Dylan Thomas」)

結合SQL操作與存儲過程

映射Java對象到SQL表中的行相當簡單,但是通常需要執行幾個SQL語句;可能是一個SELECT查找ID,然後一個INSERT插入指定ID的數據。在高度規格化(符合更高的範式,譯注)的資料庫模式中,可能需要多個表的更新,因此需要更多的語句。Java代碼會很快地膨脹,每一個語句的網路開銷也迅速增加。
將這些SQL語句轉移到一個存儲過程中將大大簡化代碼,僅涉及一次網路調用。所有關聯的SQL操作都可以在資料庫內部發生。並且,存儲過程語言,例如PL/SQL,允許使用SQL語法,這比Java代碼更加自然。早期的存儲過程,使用Oracle的PL/SQL語言編寫:

createprocereset_death_age(poetVARCHAR2,poet_ageNUMBER)
poet_idNUMBER;
beginSELECTidINTOpoet_idFROMpoetsWHEREname=poet;
INSERTINTOdeaths(mort_id,age)VALUES(poet_id,poet_age);
endset_death_age;

set_death_age幾乎可以肯定是一個很爛的實現。應該在poets表中添加一列來存儲逝世年齡。Java代碼中並不關心資料庫模式是怎麼實現的,因為它僅調用存儲過程。以後可以改變資料庫模式以提高性能,但是不必修改代碼。
下面是調用上面存儲過程的Java代碼:

publicstaticvoidsetDeathAge(PoetdyingBard,intage)throwsSQLException{
Connectioncon=null;
CallableStatementproc=null;
try{
con=connectionPool.getConnection();
proc=con.prepareCall("{callset_death_age(?,?)}");
proc.setString(1,dyingBard.getName());
proc.setInt(2,age);
proc.execute();
}
finally{
try{proc.close();}
catch(SQLExceptione){}
con.close();
}
}

為了確保可維護性,建議使用像這兒這樣的static方法。這也使得調用存儲過程的代碼集中在一個簡單的模版代碼中。如果用到許多存儲過程,就會發現僅需要拷貝、粘貼就可以創建新的方法。因為代碼的模版化,甚至也可以通過腳本自動生產調用存儲過程的代碼。

Functions

存儲過程可以有返回值,所以CallableStatement類有類似getResultSet這樣的方法來獲取返回值。當存儲過程返回一個值時,必須使用registerOutParameter方法告訴JDBC驅動器該值的SQL類型是什麼。也必須調整存儲過程調用來指示該過程返回一個值。
下面接著上面的例子。這次查詢Dylan Thomas逝世時的年齡。這次的存儲過程使用PostgreSQL的pl/pgsql:

createfunctionsnuffed_it_when(VARCHAR)returnsinteger'declare
poet_idNUMBER;
poet_ageNUMBER;
begin
--.
SELECTidINTOpoet_idFROMpoetsWHEREname=$1;
--getandreturntheage.
SELECTageINTOpoet_ageFROMdeathsWHEREmort_id=poet_id;
returnage;
end;'language'pl/pgsql';

另外,注意pl/pgsql參數名通過Unix和DOS腳本的$n語法引用。同時,也注意嵌入的注釋,這是和Java代碼相比的另一個優越性。在Java中寫這樣的注釋當然是可以的,但是看起來很凌亂,並且和SQL語句脫節,必須嵌入到Java String中。
下面是調用這個存儲過程的Java代碼:

connection.setAutoCommit(false);
CallableStatementproc=connection.prepareCall("{?=callsnuffed_it_when(?)}");
proc.registerOutParameter(1,Types.INTEGER);
proc.setString(2,poetName);
cs.execute();
intage=proc.getInt(2);

如果指定了錯誤的返回值類型會怎樣?那麼,當調用存儲過程時將拋出一個RuntimeException,正如你在ResultSet操作中使用了一個錯誤的類型所碰到的一樣。

復雜的返回值

如果這是存儲過程的全部功能,那麼存儲過程就不是其它遠程執行機制的替換方案了。存儲過程的功能比這強大得多。
當執行一個SQL查詢時,DBMS創建一個叫做cursor(游標)的資料庫對象,用於在返回結果中迭代每一行。ResultSet是當前時間點的游標的一個表示。這就是為什麼沒有緩存或者特定資料庫的支持,只能在ResultSet中向前移動。
某些DBMS允許從存儲過程中返回遊標的一個引用。JDBC並不支持這個功能,但是Oracle、PostgreSQL和DB2的JDBC驅動器都支持在ResultSet上打開到游標的指針(pointer)。
設想列出所有沒有活到退休年齡的詩人,下面是完成這個功能的存儲過程,返回一個打開的游標,同樣也使用PostgreSQL的pl/pgsql語言:

createprocerelist_early_deaths()returnrefcursoras'declare
toesuprefcursor;
begin
opentoesupforSELECTpoets.name,deaths.ageFROMpoets,deaths--allentriesindeathsareforpoets.--butthetablemightbecomegeneric.
WHEREpoets.id=deaths.mort_idANDdeaths.age<60;
returntoesup;
end;'language'plpgsql';

下面是調用該存儲過程的Java方法,將結果輸出到PrintWriter:
PrintWriter:

staticvoidsendEarlyDeaths(PrintWriterout){
Connectioncon=null;
CallableStatementtoesUp=null;
try{
con=ConnectionPool.getConnection();
//...con.
setAutoCommit(false);//Setupthecall.
CallableStatementtoesUp=connection.prepareCall("{?=calllist_early_deaths()}");
toesUp.registerOutParameter(1,Types.OTHER);
toesUp.execute();
ResultSetrs=(ResultSet)toesUp.getObject(1);
while(rs.next()){
Stringname=rs.getString(1);
intage=rs.getInt(2);
out.println(name+"was"+age+"yearsold.");
}
rs.close();
}
catch(SQLExceptione){//Weshouldprotectthesecalls.toesUp.close();con.close();
}
}

因為JDBC並不直接支持從存儲過程中返回遊標,使用Types.OTHER來指示存儲過程的返回類型,然後調用getObject()方法並對返回值進行強制類型轉換。
這個調用存儲過程的Java方法是mapping的一個好例子。Mapping是對一個集上的操作進行抽象的方法。不是在這個過程上返回一個集,可以把操作傳送進去執行。本例中,操作就是把ResultSet列印到一個輸出流。這是一個值得舉例的很常用的例子,下面是調用同一個存儲過程的另外一個方法實現:

publicclassProcessPoetDeaths{
publicabstractvoidsendDeath(Stringname,intage);
}
staticvoidmapEarlyDeaths(ProcessPoetDeathsmapper){
Connectioncon=null;
CallableStatementtoesUp=null;
try{
con=ConnectionPool.getConnection();
con.setAutoCommit(false);
CallableStatementtoesUp=connection.prepareCall("{?=calllist_early_deaths()}");
toesUp.registerOutParameter(1,Types.OTHER);
toesUp.execute();
ResultSetrs=(ResultSet)toesUp.getObject(1);
while(rs.next()){
Stringname=rs.getString(1);
intage=rs.getInt(2);
mapper.sendDeath(name,age);
}
rs.close();
}catch(SQLExceptione){//Weshouldprotectthesecalls.toesUp.close();
con.close();
}
}

這允許在ResultSet數據上執行任意的處理,而不需要改變或者復制獲取ResultSet的方法:

staticvoidsendEarlyDeaths(finalPrintWriterout){
ProcessPoetDeathsmyMapper=newProcessPoetDeaths(){
publicvoidsendDeath(Stringname,intage){
out.println(name+"was"+age+"yearsold.");
}
};
mapEarlyDeaths(myMapper);
}

這個方法使用ProcessPoetDeaths的一個匿名實例調用mapEarlyDeaths。該實例擁有sendDeath方法的一個實現,和我們上面的例子一樣的方式把結果寫入到輸出流。當然,這個技巧並不是存儲過程特有的,但是和存儲過程中返回的ResultSet結合使用,是一個非常強大的工具。

6. 在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;

7. java中如何調用資料庫的存儲過程

Java調用存儲過程的方法是通過調用Connection的實例方法prepareCall,prepareCall方法返回CallableStatement對象用於填充存儲過程的參數。prepareCall方法形參是調用存儲過程的sql語句,此參數的語法格式如下:

{callstoredProcereName(parameter-list)}

其中,storedProcereName是存儲過程名稱,parameter-list是存儲過程參數列表。

例如,存儲過程名為usp_test,有兩個輸入參數a,b。則調用代碼看起來如下所示:

=connection.prepareCall("{callusp_test(?,?)}");
callableStatement.setObject("a","value-1");
callableStatement.setObject("b","value-2");
callableStatement.execute();
熱點內容
xp區域網共享無法訪問 發布:2025-07-26 07:41:26 瀏覽:792
ie腳本錯誤找不到成員 發布:2025-07-26 07:29:45 瀏覽:504
勿忘我最低配置是什麼 發布:2025-07-26 07:29:45 瀏覽:292
c語言fdset 發布:2025-07-26 07:29:03 瀏覽:971
php購物車的實現 發布:2025-07-26 07:25:29 瀏覽:600
國內最大電腦伺服器 發布:2025-07-26 07:24:47 瀏覽:403
小程序源碼論壇 發布:2025-07-26 07:15:23 瀏覽:81
ac語言表達式是 發布:2025-07-26 06:50:51 瀏覽:822
linux中安裝軟體 發布:2025-07-26 06:45:33 瀏覽:453
responsejava 發布:2025-07-26 06:45:31 瀏覽:599