在java中使用存储过程

我们知道:存储过程是预先写好的一组SQL语句。

创建存储过程的使用CREAT PROCEDURE语句,语法如下:

CREATE PROCEDURE procedure_name
 参数定义
AS
 存储过程主体SQL语句

在调用时,存储过程的名称及指定的参数通过JDBC连接发送给DBMS,执行存储过程并通过连接(如果有)返回结果。

使用存储过程拥有和使用基于EJB或CORBA这样的应用服务器一样的好处。区别是存储过程可以从很多流行的DBMS中免费使用,而应用服务器大都非常昂贵。这并不只是许可证费用的问题。使用应用服务器所需要花费的管理、编写代码的费用,以及客户程序所增加的复杂性,都可以通过DBMS中的存储过程所整个地替代。

你可以使用Java,Python,Perl或C编写存储过程,但是通常使用你的DBMS所指定的特定语言。Oracle使用PL/SQL,PostgreSQL使用pl/pgsql,DB2使用Procedural SQL。这些语言都非常相似。并且,存储过程是为嵌入SQL所设计,这使得它们比Java或C等语言更加友好地方式表达数据库的机制。

存储过程保存在数据库中,以后可以反复调用,并可单独修改维护。因为存储过程运行在DBMS自身,这可以帮助减少应用程序中的等待时间。不是在Java代码中执行5个或8个SQL语句,而只需要在服务器端执行1个存储过程,这样能减少网络流量。

JDBC通过CallableStatement类支持存储过程的调用。该类实际上是PreparedStatement的一个子类。

假设我们数据库里面有张表叫users,定义如下:
CREATE TABLE users (
 userid int IDENTITY (1, 1) NOT NULL PRIMARY KEY,
 username varchar (20) NOT NULL ,
 userage tinyint NOT NULL,
 CHECK (userage > 1 and userage < 100)
)


该数据库中有一个插入记录的存储过程:insertUserProcedure:
CREATE PROCEDURE insertUserProcedure
@userid int output,
@username varchar(20),
@userage tinyint
As Set NOCOUNT ON
If Exists (select userid from users Where username =@username) RETURN 0
ELSE
Begin
 INSERT INTO users (username,userage) VALUES(@username,@userage) SET @userid=@@IDENTITY RETURN 1
End
GO


调用代码如下:

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:sqlserver://localhost:1433;databaseName=test;user=alex;password=Abcd1234";
Connection conn = null;
CallableStatement cstmt = null;
try
{
 conn = DriverManager.getConnection(url);
 cstmt = conn.prepareCall("{? = call insertUserProcedure(?,?,?)}");
 cstmt.registerOutParameter(1,Types.TINYINT);
 cstmt.setString(2,"alex"); //插入新记录的时候修改这里,因为在存储过程约束了username的唯一性。
 cstmt.setInt(3,50);
 cstmt.registerOutParameter(4,Types.INTEGER);
 cstmt.execute();
 int returnValue =cstmt.getInt(1);
 int userid = cstmt.getInt(4);
 if(returnValue == 1)
 {
  out.println("Insert Success!");
  out.println("UserID = " + userid);
  out.println("returnValue = " + returnValue);
 }
 else
 {
  out.println("Insert Failure!");
 }
}
catch(Exception ex)
{
 out.print("=== "+ex.getLocalizedMessage());
}
finally
{
 try
 {
  if(cstmt != null)
  {
   cstmt.close();
   cstmt = null;
  }
  if(conn != null)
  {
   conn.close();
   conn = null;
  }
 }
 catch(Exception e)
 {
  e.printStackTrace();
 }

如果指定了错误的返回值类型会怎样?那么,当调用存储过程时将抛出一个RuntimeException,正如你在ResultSet操作中使用了一个错误的类型所碰到的一样。

如果返回的是集合,则把返回结果转化为ResultSet,然后通过循环遍历集合:

ResultSet rs = (ResultSet) cstmt.getObject(1);
while (rs.next()) {
 String username = rs.getString("username");
 int userage = rs.getInt("userage");
 out.println(username + " is " + userage+ "years old");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值