使用存储过程

原创 2012年03月23日 09:58:30

很多数据库都支持在数据库内部执行的函数。这种方法有几个好处,包括更快的性能和改进的安全性。这些函数称为存储过程。存储过程是用来封装SQL语句来完成一个完整的业务功能,类似于面向对象里面方法的概念。虽然它们通常是用SQL编写的,但也可以用数据库支持的任何编程语言编写。随着Java语言日趋流行,几个数据库厂商---Oracle(Oracle数据库)和IBM(db2数据库)都起用了Java语言创建存储过程,还可以在不同数据库之间移动存储过程。

存储过程可以支持三种类型的参数:IN,OUT和INOUT,这对于存储过程在数据库内部真正能做什么来说,带来了很大的灵活性。不管存储过程是用什么语言编写的,它都能以一种标准的方式从Java应用程序调用。

首先,您需要创建一个CallableStatement对象。为了标识存储过程和过程需要的参数的类型和数量,还要允许使用三种类型的调用。下面的清单说明了这三种类型(假定我们正在调用一个名为StudentList的存储过程):

n {call StudentList}如果过程不需要参数

n {call StudentList(?,?)}如果过程需要两个参数

n {?=call StudentList(?,?)}如果参数需要两个参数并返回一个

要想使用存储过程,首先应该创建一个存储过程!

代码的实现

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.naming.NamingException;

public class CreateStoredProceduresofSQLServer {
	public static void main(String[] args) {
		Connection con = null;
		Statement stmt = null;
		String jndiname = "jdbcPool/mydatasource";

		try {
			con = DBCon.getConnectionFromPooledDataSource(jndiname);
			stmt = con.createStatement();

			// 1.创建存储过程show_students
			String createProcedure1 = "create procedure show_students " + "as "	+ "select id, name,age " + "from students " + "order by id";
			// 删除数据库中存在的同名过程
			stmt.executeUpdate("if exists(select name from sysobjects "
					+ "where name='show_students'and type='p') "
					+ "drop procedure show_students");
			stmt.executeUpdate(createProcedure1);

			// 2.创建储存过程onestudent
			String createProcedure2 = "create procedure onestudent "
					+ "@stu_id int = null, " + "@name varchar(20) output, "
					+ "@age  int  output " + "as " + "if @stu_id = null "
					+ "BEGIN "
					+ "  PRINT 'ERROR: You must specify a stu_id value.' "
					+ "  RETURN "
					+ "END "
					+
					// Get the sales for the specified cof_name and " +
					// assign it to the output parameter. " +
					"SELECT @name = name, @age = age " + "FROM coffees "
					+ "WHERE id = @stu_id " + "RETURN ";
			stmt.executeUpdate("if exists(select name from sysobjects "
					+ "where name='onestudent'and type='p') "
					+ "drop procedure onestudent");
			stmt.executeUpdate(createProcedure2);

			// 3.创建函数
			String createProcedure3 = "CREATE FUNCTION pubuse.ageofstu "
					+
					// Input cof_name
					"(@stu_name varchar(20)) "
					+ "RETURNS int "
					+ // return sales
					"AS " + "BEGIN " + "  DECLARE @age int "
					+ "  SELECT @age = age " + "  FROM student "
					+ "  WHERE name like @stu_name " + "  RETURN @age "
					+ "END ";
			stmt.executeUpdate("if exists(select name from sysobjects "
					+ "where name='ageofstu') "
					+ "drop function pubuse.ageofstu");
			stmt.executeUpdate(createProcedure3);
			stmt.close();
			con.close();
		} catch (NamingException ex) {
			System.err.println("Name Not Bound : " + ex.getMessage());
		} catch (SQLException ex) {
			System.err.println("SQLException : " + ex.getMessage());
		}
		System.out.println("程序执行结束!");
	}
}

下面是使用存储过程的代码:

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import javax.naming.NamingException;

public class InvokeStoreProcdureofSQLServer {
	public static void main(String[] args) {
		Connection con = null;
		String jndiname = "jdbcPool/mydatasource";
		// 定义调用存储过程和函数的 SQL 语句
		String callSQL1 = "{call show_students}";
		String callSQL2 = "{call onestudent(?,?,?)}";
		String callSQL3 = "{? = call ageofstu(?)}";

		try {
			con = DBCon.getConnectionFromPooledDataSource(jndiname);
			// 调用第 1 个存储过程
			CallableStatement cs = con.prepareCall(callSQL1);
			ResultSet rs = cs.executeQuery();
			System.out.println("第一个存储过程调用结果");
			while (rs.next()) {
				String id = rs.getString(1);
				String name = rs.getString(2);
				String age = rs.getString(3);
				System.out.println(id + "  " + name + " " + age);
			}
			// 调用第 2 个存储过程
			cs = con.prepareCall(callSQL2);
			cs.setString(1, "2");
			cs.registerOutParameter(2, Types.CHAR);
			cs.registerOutParameter(3, Types.INTEGER);
			cs.execute();
			String name = cs.getString(2);
			int age = cs.getInt(3);
			System.out.println("第二个存储过程调用结果");
			System.out.println("This student's name is " + name
					+ " and age is " + age);
			// 调用函数
			cs = con.prepareCall(callSQL3);
			cs.setString(2, "小罗");
			cs.registerOutParameter(1, Types.INTEGER);
			cs.execute();
			age = cs.getInt(1);
			System.out.println("函数调用结果");
			System.out.println("This student's name is " + age + ".");
			cs.close();
			con.close();
		} catch (NamingException ex) {
			System.err.println("Name Not Bound : " + ex.getMessage());
		} catch (SQLException ex) {
			System.err.println("SQLException : " + ex.getMessage());
		}
		System.out.println("调用结束!");
	}
}


为什么要用存储过程,什么时候要用存储过程,存储过程的优点

  为什么要用存储过程    几个去 IBM 面试的兄弟回来抱怨:去了好几个不同的 IBM 项目组,几乎每个面试官问到数据库的时候都要问用没用过存储过程,烦人不?大家去面的程序员,又不是 DBA,以前...
  • defonds
  • defonds
  • 2009年07月15日 11:45
  • 12970

with as在存储过程使用

create or replace procedure strToken is    int var_count:=0;    int var_count1:=0; begin    with...
  • jji8877032
  • jji8877032
  • 2015年04月17日 09:40
  • 820

该不该用存储过程

转:减少存储过程封装业务逻辑-web开发与传统软件开发的思维模式不同 本篇文章讨论并不是:不要使用存储过程,因为有些事情还是要存储过程来完成,不可能不用。而是关于:"业务逻辑是不是要封装在存储过...
  • java_gchsh
  • java_gchsh
  • 2018年01月23日 15:02
  • 118

绑定变量 存储过程

绑定变量是为了减少解析的,比如你有个语句这样 select aaa,bbb from ccc where ddd=eee; 如果经常通过改变eee这个谓词赋值来查询,像如下 select aaa...
  • jeff_2009
  • jeff_2009
  • 2011年01月18日 15:48
  • 1563

SQL存储过程使用介绍

在数据库编程过程中经常会用到存储过程 , 相比 SQL 语句 , 存储过程更方便 , 快速 , 安全 ; 先将存储过程的相关介绍和使用方法总结如下 ;1. 存储过程的概念存储过程 (Stored Pr...
  • tojohnonly
  • tojohnonly
  • 2017年04月25日 13:54
  • 2874

Sybase存储过程的使用

导读:存储过程p_RsGz_JiNeng_Rtn向调用者返回一个存储在变量@ErrCode里的值,这个值被称为状态值,它向调用者反映存储过程执行的成败状态(三)。...
  • u011598529
  • u011598529
  • 2014年09月20日 14:01
  • 1040

mysql 变量使用,存储过程

set语句的学习: 使用select定义用户变量的实践 将如下语句改成select的形式:  set @VAR=(select sum(amount) from penalties); 我的修改: ...
  • bao19901210
  • bao19901210
  • 2016年01月28日 17:56
  • 1699

为什么要用存储过程?

存储过程概念 存储过程是一些sql语句和控制语句组成的被封装起来的过程,它驻留在数据库中,可以被客户应用程序通过存储过程名字调用,也可以从另一个存储过程或触发器调用。 它的参数可以被传递和返回,与...
  • u010796790
  • u010796790
  • 2016年08月12日 19:59
  • 447

存储过程中绑定变量

Create Or Replace Procedure test3 (empno  number) Is     v_eno number := empno;     v_ename varcha...
  • wll_1017
  • wll_1017
  • 2014年12月11日 16:52
  • 2710

ibatis对存储过程的调用

IBatis映射文件: [xhtml] view plaincopy xml version="1.0" encoding="UTF-8" ?>  ...
  • hemin1003
  • hemin1003
  • 2015年05月21日 01:16
  • 787
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用存储过程
举报原因:
原因补充:

(最多只允许输入30个字)