java中如何运用存储过程

来源:互联网 发布:java jit编译器 编辑:程序博客网 时间:2024/05/25 01:35

如何在JDBC驱动程序下使用存储过程
说明:本文档是在微软的官方文档的基础上整理,如有疑问请联系学术部:罗剑老师。Email:jian.luo@xfaccp.com
适用于:sqlserver2005


使用 JDBC 驱动程序调用带参数的存储过程时,必须结合 SQLServerConnection 类的 prepareCall 方法使用 call SQL 转义序列。 call 转义序列的完整语法如下:

{[?=]call procedure-name[([parameter][,[parameter]]...)]}


下面我分别讨论在JDBC驱动程序下使用各种存储过程


一、使用不带参数的存储过程
使用 JDBC 驱动程序调用不带参数的存储过程时,必须使用 call SQL 转义序列。不带参数的 call 转义序列的语法如下所示:
{call procedure-name}

在 SQL Server 2005 AdventureWorks 示例数据库中创建

以下存储过程作为实例:
CREATE PROCEDURE GetContactFormalNames
AS
BEGIN
  SELECT TOP 10 Title + ' ' + FirstName + ' ' +

LastName AS FormalName
  FROM Person.Contact
END

然后使用 executeQuery 方法调用 GetContactFormalNames 存储过程。

public static void executeSprocNoParams(Connection con) {
  try {
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery("{call dbo.GetContactFormalNames}");

      while (rs.next()) {
        System.out.println(rs.getString("FormalName"));
      }
      rs.close();
      stmt.close();
  }
  catch (Exception e) {
      e.printStackTrace();
  }
}

二、使用带有输入参数的存储过程

使用 JDBC 驱动程序调用带参数的存储过程时,必须结合 SQLServerConnection 类的 prepareCall 方法使用 call

SQL 转义序列。带有 IN 参数的 call 转义序列的语法如下所示:

{call procedure-name[([parameter][,[parameter]]...)]}

构造 call 转义序列时,请使用 ?(问号)字符来指定 IN 参数。此字符充当要传递给该存储过程的参数值的占位符。可以使用 SQLServerPreparedStatement 类的

setter 方法之一为参数指定值。可使用的 setter 方法由 IN 参数的数据类型决定。向 setter 方法传递值时,不仅需要指定要在参数中使用

的实际值,还必须指定参数在存储过程中的序数位置。例如,如果存储过程包含单个 IN 参数,则其序数值为 1。如果存储过程包含两个参数,则第一个序数值为 1,第二个序数值为 2。

作为如何调用包含 IN 参数的存储过程的实例,使用 SQL

Server 2005 AdventureWorks 示例数据库中的 uspGetEmployeeManagers 存储过程。此存储过程接受名为 EmployeeID 的单个输入参数(它是一个整数值),然

后基于指定的 EmployeeID 返回雇员及其经理的递归列表。下面是调用此存储过程的 Java 代码:

public static void executeSprocInParams(Connection con) {
  try {
      PreparedStatement pstmt = con.prepareStatement("{call dbo.uspGetEmployeeManagers(?)}");
      pstmt.setInt(1, 50);
      ResultSet rs = pstmt.executeQuery();

      while (rs.next()) {
        System.out.println("EMPLOYEE:");
        System.out.println(rs.getString("LastName") + ", " + rs.getString("FirstName"));
        System.out.println("MANAGER:");
        System.out.println(rs.getString("ManagerLastName") + ", " + rs.getString("ManagerFirstName"));
        System.out.println();
      }
      rs.close();
      pstmt.close();
  }

  catch (Exception e) {
      e.printStackTrace();

三、使用带有输出参数的存储过程

您可以调用的 SQL Server 存储过程是返回一个或多个 OUT 参数的存储过程,存储过程使用这些参数将数据返回到调用它的应用程序。可以使用 Microsoft SQL Server

2005 JDBC Driver 提供的 SQLServerCallableStatement 类,调用此类存储过程并处理其返回的数据。

使用 JDBC 驱动程序调用此类存储过程时,必须结合 SQLServerConnection 类的 prepareCall 方法使用 call

SQL 转义序列。带有 OUT 参数的 call 转义序列的语法

如下所示:

{call procedure-name[([parameter][,

[parameter]]...)]}

CREATE PROCEDURE GetImmediateManager
  @employeeID INT,
  @managerID INT OUTPUT
AS
BEGIN
  SELECT @managerID = ManagerID
  FROM HumanResources.Employee
  WHERE EmployeeID = @employeeID
END
根据指定的整数 IN 参数 (employeeID),该存储过程也返回单个整数 OUT 参数 (managerID)。根据

HumanResources.Employee 表中包含的 EmployeeID,OUT 参数中返回的值为 ManagerID。

在下面的实例中,将向此函数传递 AdventureWorks 示例数据库的打开连接,然后使用 execute 方法调用

GetImmediateManager 存储过程:

public static void executeStoredProcedure

(Connection con) {
  try {
      CallableStatement cstmt = con.prepareCall

("{call dbo.GetImmediateManager(?, ?)}");
      cstmt.setInt(1, 5);
      cstmt.registerOutParameter(2,

java.sql.Types.INTEGER);
      cstmt.execute();
      System.out.println("MANAGER ID: " +

cstmt.getInt(2));
  }
  catch (Exception e) {
      e.printStackTrace();
  }
}
本示例使用序号位置来标识参数。或者,也可以使用参数的名称(而非其序号位置)来标识此参数。下面的代码示例修改了上一个示例,以说明如何在 Java 应用程序中使

用命名参数。请注意,这些参数名称对应于存储过程的定义中的参数名称:

public static void executeStoredProcedure(Connection con) {
  try {
      CallableStatement cstmt = con.prepareCall("{call dbo.GetImmediateManager(?, ?)}");
      cstmt.setInt("employeeID", 5);
      cstmt.registerOutParameter("managerID", java.sql.Types.INTEGER);
      cstmt.execute();
      System.out.println("MANAGER ID: " + cstmt.getInt("managerID"));
      cstmt.close();
  }
  catch (Exception e) {
      e.printStackTrace();
  }
}


四、使用带有返回状态的存储过程

您可以调用的 SQL Server 存储过程是一个返回状态或结果参数的存储过程。这通常用于指示存储过程执行成功还

是失败。可以使用 Microsoft SQL Server 2005 JDBC Driver 提供的 SQLServerCallableStatement 类,调用此类存储过程并处理其返回的数据。

使用 JDBC 驱动程序调用这种存储过程时,必须结合 SQLServerConnection 类的 prepareCall 方法使用 call SQL 转义序列。返回状态参数的 call 转义序列的语法如

下所示:

{[?=]call procedure-name[([parameter][,[parameter]]...)]}

构造 call 转义序列时,请使用 ?(问号)字符来指定返回状态参数。此字符充当要从该存储过程返回的参数值的占位符。要为返回状态参数指定值,必须在执行存储过程

前使用 SQLServerCallableStatement 类的 registerOutParameter 方法指定参数的数据类型。

注意: 当 JDBC 驱动程序与 SQL Server 数据库一起使用时,registerOutParameter 方法中为返回状态参数指定的值将始终为整数,您可通过使用

java.sql.Types.INTEGER 数据类型进行指定。

此外,向 registerOutParameter 方法传递返回状态参数值时,不仅需要指定要使用的参数的数据类型,还必须指定参数在存储过程中的序数位置。对于返回状态参数,其

序数位置始终为 1,这是因为它始终是调用存储过程时的第一个参数。尽管 SQLServerCallableStatement 类支持使用参数的名称来指示特定参数,但您只能对返回状态参数使用参数的序号位置编号。

作为实例,在 SQL Server 2005 AdventureWorks 示例数

据库中创建以下存储过程:

CREATE PROCEDURE CheckContactCity
  (@cityName CHAR(50))
AS
BEGIN
  IF ((SELECT COUNT(*)
  FROM Person.Address
  WHERE City = @cityName) > 1)
  RETURN 1
ELSE
  RETURN 0
END
该存储过程返回状态值 1 或 0,这取决于是否能在表 Person.Address 中找到 cityName 参数指定的城市。在下面的实例中,将向此函数传递 AdventureWorks 示例

数据库的打开连接,然后使用 execute 方法调用 CheckContactCity 存储过程:

public static void executeStoredProcedure(Connection con) {
  try {
      CallableStatement cstmt = con.prepareCall("{? = call dbo.CheckContactCity(?)}");
      cstmt.registerOutParameter(1, java.sql.Types.INTEGER);
      cstmt.setString(2, "Atlanta");
      cstmt.execute();
      System.out.println("RETURN STATUS: " + cstmt.getInt(1));
  }
  cstmt.close();
  catch (Exception e) {
      e.printStackTrace();
  }
}

五、使用带有更新计数的存储过程

为了使用存储过程修改 SQL Server 数据库中的数据,Microsoft SQL Server 2005 JDBC Driver 提供了 SQLServerCallableStatement 类。通过使用 SQLServerCallableStatement 类,可以调用修改数据库中所包含数据的存储过程,然后返回受影响的行数计数(也称为更新计数)。

使用 SQLServerCallableStatement 类构建对存储过程的调用之后,可以使用 execute 或 executeUpdate 方法中的任意一个来调用此存储过程。executeUpdate 方法将返回一个 int 值,该值包含受此存储过程影响的行数,但 execute 方法不返回此值。如果使用 execute 方法,并且希望获得受影响的行数计数,则可以在运行存储过程后调用 getUpdateCount 方法。

注意: 如果要让 JDBC 驱动程序返回所有更新计数,包括任何可能已不再使用的触发器所返回的更新计数,请将 lastUpdateCount 连接字符串属性设置为“false”。有关 lastUpdateCount 属性的详细信息,请参阅设置连接属性。

作为实例,在 SQL Server 2005 AdventureWorks 示例数据库中创建以下表和存储过程:

CREATE TABLE TestTable
  (Col1 int IDENTITY,
    Col2 varchar(50),
    Col3 int);

CREATE PROCEDURE UpdateTestTable
  @Col2 varchar(50),
  @Col3 int
AS
BEGIN
  UPDATE TestTable
  SET Col2 = @Col2, Col3 = @Col3
END;
在下面的实例中,将向此函数传递 AdventureWorks 示例数据库的打开连接,并使用 execute 方法调用 UpdateTestTable 存储过程,然后使用 getUpdateCount 方法返回受存储过程影响的行计数。

public static void executeUpdateStoredProcedure(Connection con) {
  try {
      CallableStatement cstmt = con.prepareCall("{call dbo.UpdateTestTable(?, ?)}");
      cstmt.setString(1, "A");
      cstmt.setInt(2, 100);
      cstmt.execute();
      int count = cstmt.getUpdateCount();
      cstmt.close();

      System.out.println("ROWS AFFECTED: " + count);
  }
  catch (Exception e) {
      e.printStackTrace();
  }

原创粉丝点击