存储过程

[size=medium]
[b]存储过程基本概念[/b]
数据库存储过程是一组预先创建并用指定的名称存储在数据库服务器上的 SQL 语句,将使用比较频繁或者比较复杂的操作,预先用 SQL 语句写好并用一个指定的名称存储起来,以后当需要数据库提供与已定义好的存储过程的功能相同的服务时,只需再次执行该存储过程。

数据库存储过程具有如下优点:

1.存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL 语句每执行一次就编译一次,因此使用存储过程可以大大提高数据库执行速度。
2.通常,复杂的业务逻辑需要多条 SQL 语句。这些语句要分别地从客户机发送到服务器,当客户机和服务器之间的操作很多时,将产生大量的网络传输。如果将这些操作放在一个存储过程中,那么客户机和服务器之间的网络传输就会大大减少,降低了网络负载。
3.存储过程创建一次便可以重复使用,从而可以减少数据库开发人员的工作量。
4.安全性高,存储过程可以屏蔽对底层数据库对象的直接访问,使用 EXECUTE 权限调用存储过程,无需拥有访问底层数据库对象的显式权限。
[b]
使用 JDBC API 直接调用存储过程[/b]

Java Database Connectivity (JDBC) API 是 J2EE 的一部分,是 Java 语言访问关系数据库的基于标准的首要机制,提供了对数据库访问和缓存管理的直接控制。

JDBC 中的 CallableStatement 对象为所有的关系数据库管理系统 (RDBMS: Relational Database Management System) 提供了一种标准形式调用存储过程的方法。对存储过程的调用有两种形式:带结果参数和不带结果参数。结果参数是一种输出参数,是存储过程的返回值。两种形式都可带有数量可变的输入(IN 参数)、输出(OUT 参数)或输入和输出(INOUT 参数)的参数。

在 JDBC 中调用存储过程的语法为:{call procedure_name[(?, ?, ...)]};返回结果参数的存储过程的语法为:{? = call procedure_name[(?, ?, ...)]};不带参数的存储过程的语法为:{call procedure_name}。其中,问号代表参数,方括号表示其间的内容是可选项。

[b][color=red]使用 CallableStatement 对象调用存储过程的过程如下:[[/color]/b]

1.使用 Connection.prepareCall 方法创建一个 CallableStatement 对象。
2.使用 CallableStatement.setXXX 方法给输入参数(IN)赋值。
3.使用 CallableStatement.registerOutParameter 方法来指明哪些参数只做输出参数(OUT),哪些是输入输出参数(INOUT)。
4.调用以下方法之一来调用存储过程:
-->int CallableStatement.executeUpdate: 存储过程不返回结果集。
-->ResultSet CallableStatement.executeQuery: 存储过程返回一个结果集。
-->Boolean CallableStatement.execute: 存储过程返回多个结果集。
-->int[] CallableStatement.executeBatch: 提交批处理命令到数据库执行。
5.如果存储过程返回结果集,则得到其结果集。
6.调用 CallableStatement.getXXX 方法从输出参数 (OUT) 或者输入输出参数 (INOUT) 取值。
7.使用完 CallableStatement 对象后,使用 CallableStatement.close 方法关闭 CallableStatement 对象。

[b]1. 使用 executeUpdate 来执行的存储过程
[/b][/size]
Connection con = null; 
...
// Create a CallableStatement object
CallableStatement cstmt = con.prepareCall("CALL exampleJDBC (?, ?, ?, ?, ?)");
cstmt.setString (1, “BeiJing”); // Set input parameter
cstmt.setInt (2, 2008); // Set input parameter
cstmt.registerOutParameter (3, Types.INTEGER);
cstmt.registerOutParameter (4, Types.INTEGER);
cstmt.registerOutParameter (5, Types.VARCHAR);
cstmt.executeUpdate(); // Call the stored procedure
int goldnumber = cstmt.getInt(3); // Get the output parameter values
int silvernumber = cstmt.getInt(4);
String errorinfo = cstmt.getString(5);
cstmt.close();

当存储过程返回一个结果集时,只需遍历该结果集便可以得到存储过程执行的所有结果。

[b]2. 存储过程返回一个结果集[/b]
				
CallableStatement cstmt = null;

boolean moreResultSets = cstmt.execute();
ResultSet rs1 = cstmt.getResultSet();
while (rs1.next())
System.out.println(rs1.getString(1) + " " + rs1.getString(2));

当存储过程返回多个结果集时,遍历所有结果集才能得到执行的所有结果,使用 getMoreResults() 方法跳转到下一个结果集。

[b]3. 存储过程返回多个结果集
[/b]
CallableStatement cstmt = null; 

While (cstmt.getMoreResults()) {
ResultSet rs2 = cstmt.getResultSet();
while (rs2.next())
System.out.println(rs2.getString(1) + " " + rs2.getString(2));
rs2.close();
}



[b][color=red]如果存储过程返回多个结果集,每个结果集的数据结构都不一样,或者某些结果集的数据结构未知,则可以使用 getColumnName() 方法来得到结果集中数据的列名。[/color][/b]

CallableStatement cstmt = null; 

boolean moreResultSets = cstmt.execute();
while (moreResultSets) {
ResultSet rs = cstmt.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
StringBuffer buffer = new StringBuffer();
for (int i = 1; i <= rsmd.getColumnCount(); i++){
buffer.append(rsmd.getColumnName(i)).append("\t");
System.out.println(buffer.toString());
while (rs.next()) {
buffer.setLength(0);
for (int i = 1; i <= rsmd.getColumnCount(); i++)
buffer.append(rs.getString(i)).append("\t");
System.out.println(buffer.toString());
}
}
rs.close();
moreResultSets = cstmt.getMoreResults();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值