Posted on 2009-12-20 01:08
啥都寫點 閱讀(283)
評論(0) 編輯 收藏 所屬分類:
J2SE
假設給一個名為studentdb的數據庫創建若干個存儲過程,SQL腳本如下:
user studentdb;
delimiter //
create procedure my_count_proc (IN scorevalue INT, OUT no INT)
BEGIN
SELECT count(*) INTO no from student_basic where score >= scorevalue;
end
//
delimiter ;
delimiter //
create procedure my_count_proc1 (OUT no INT)
BEGIN
SELECT count(*) INTO no from student_basic;
end
//
delimiter ;
delimiter //
create procedure my_insert_proc()
BEGIN
INSERT INTO student_basic (name, age, score) VALUES ('testproc', 18, 81);
end
//
delimiter ;
delimiter //
create procedure my_insert_proc1(IN agevalue INT)
BEGIN
INSERT INTO student_basic (name, age, score) VALUES ('testproc1', agevalue, 81);
end
//
delimiter ;
sdf

存儲過程存在于數據庫中,它完成一定的功能,將常用的數據庫操作寫成存儲過程再執行,比寫成程序再執行更加有效,目前一般的數據庫都支持存儲過程。

DatabaseMetaData的getProcedures方法可以獲得數據庫的所有存儲過程。

執行存儲過程需要使用java.sql.CallableStatement接口,它實現了PreparedStatement接口,通過Connection的getProcedures方法創建CallableStatement對象,調用CallableStatement的execute方法執行存儲過程。

在調用有參數的存儲過程時,需要使用動態SQL語句,對于輸入參數,使用PreparedStatement提供的set系列方法,為輸入參數賦值;對于輸出參數,必須使用CallableStatement的registerOutParameter方法注冊輸出參數的類型。

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;


/** *//**
* 獲取、創建、調用數據庫的存儲過程
*/

public class StorageProcedure
{


/** *//**
* 列出數據庫中所有的存儲過程名
* @param con 數據庫的連接
*/

public static void listStorageProcedureName(Connection con)
{

try
{
// 獲得數據庫的元數據
DatabaseMetaData md = con.getMetaData();
// 獲得所有的存儲過程的描述
ResultSet resultSet = md.getProcedures(null, null, "%");
//顯示存儲過程名,位于結果集的第三個字段
System.out.println("數據庫現有的存儲過程名為:");

while (resultSet.next())
{
String procName = resultSet.getString(3);
System.out.print(procName + "\t");
}
System.out.println();

} catch (SQLException e)
{
e.printStackTrace();
}
}

/** *//**
* 調用存儲過程
* @param con
*/

public static void callStorageProcedure(Connection con)
{
CallableStatement cs = null;

try
{

/** *//*** 調用無參數的存儲過程 ***/
// 該存儲過程往數據表中插入一條數據
cs = con.prepareCall("{call my_insert_proc()}");
cs.execute();

/** *//**** 調用有一個輸入參數的存儲過程 ****/
// 該存儲過程往數據表中插入一條數據,其中有一列的值為參數值
cs = con.prepareCall("{call my_insert_proc1(?)}");
//設置參數
cs.setInt(1, 18);
// 執行
cs.execute();

/** *//*** 調用有一個輸出參數的存儲過程 ****/
// 該存儲過程返回數據表中的記錄數
cs = con.prepareCall("{call my_count_proc1(?)}");
// 注冊輸出參數的類型
cs.registerOutParameter(1, Types.INTEGER);
// 執行
cs.execute();
// 獲取輸出參數的值
int outParam = cs.getInt(1);
System.out.println("my_count_proc1() 執行結果:" + outParam);

/** *//*** 調用有一個輸入參數和一個輸出參數的存儲過程 ***/
// 該存儲過程返回數據表中score>輸入參數的記錄數
cs = con.prepareCall("{call my_count_proc(?,?)}");
// 注冊輸出參數的類型
cs.registerOutParameter(2, Types.INTEGER);
// 設置輸入參數的值
cs.setInt(1, 90);
// 執行
cs.execute();
// 獲取輸出參數的值
outParam = cs.getInt(2);
System.out.println("my_count_proc 執行結果:" + outParam);

} catch (SQLException e)
{
e.printStackTrace();

} finally
{
OperateDB.closeStatement(cs);
}
}
public static void main(String[] args) throws ClassNotFoundException,

SQLException
{
String dbName = "studentdb";
String userName = "test";
String password = "test";

Connection con = null;

try
{
// 獲得數據庫連接
con = DBConnector.getMySQLConnection(null, null, null, dbName,
userName, password);
// 列出數據庫的所有存儲過程名
StorageProcedure.listStorageProcedureName(con);
// 調用存儲過程
StorageProcedure.callStorageProcedure(con);

} catch (ClassNotFoundException e1)
{
throw e1;

} catch (SQLException e2)
{
throw e2;

} finally
{
// 關閉數據庫連接
OperateDB.closeConnection(con);
}
}
}

--
學海無涯