(转)Java调用SQL Server的存储过程详解

本文转载自:http://dev.yesky.com/128/8088128.shtml

1使用不带参数的存储过程

  使用 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

此存储过程返回单个结果集,其中包含一列数据(由 Person.Contact 表中前十个联系人的称呼、名称和姓氏组成)。

  在下面的实例中,将向此函数传递 AdventureWorks 示例数据库的打开连接,然后使用 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();

  }
  }

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

  使用 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();
   }
  }

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

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

  





以下是引用片段:
{call procedure-name[([parameter][,[parameter]]...)]}

  构造 call 转义序列时,请使用 ?(问号)字符来指定 OUT 参数。此字符充当要从该存储过程返回的参数值的占位符。要为 OUT
参数指定值,必须在运行存储过程前使用 SQLServerCallableStatement 类的 registerOutParameter
方法指定各参数的数据类型。

  使用 registerOutParameter 方法为 OUT 参数指定的值必须是 java.sql.Types 所包含的 JDBC
数据类型之一,而它又被映射成本地 SQL Server 数据类型之一。有关 JDBC 和 SQL Server 数据类型的详细信息,请参阅了解 JDBC
驱动程序数据类型。

  当您对于 OUT 参数向 registerOutParameter
方法传递一个值时,不仅必须指定要用于此参数的数据类型,而且必须在存储过程中指定此参数的序号位置或此参数的名称。例如,如果存储过程包含单个 OUT
参数,则其序数值为 1;如果存储过程包含两个参数,则第一个序数值为 1,第二个序数值为 2。

  作为实例,在 SQL Server 2005 AdventureWorks 示例数据库中创建以下存储过程: 根据指定的整数 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应用程序中使用命名参数。请注意,这些参数名称对应于存储过程的定义中的参数名称: CREATE PROCEDURE GetImmediateManager

  





以下是引用片段:
 @employeeID INT,

   @managerID INT OUTPUT
  AS
  BEGIN

   SELECT @managerID = ManagerID

   FROM HumanResources.Employee

   WHERE EmployeeID = @employeeID
  END

  存储过程可能返回更新计数和多个结果集。Microsoft SQL Server 2005 JDBC Driver 遵循 JDBC 3.0
规范,此规范规定在检索 OUT 参数之前应检索多个结果集和更新计数。也就是说,应用程序应先检索所有 ResultSet 对象和更新计数,然后使用
CallableStatement.getter 方法检索 OUT 参数。否则,当检索 OUT 参数时,尚未检索的 ResultSet
对象和更新计数将丢失。

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

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

 





以下是引用片段:
 {[?=]call procedure-name[([parameter][,[parameter]]...)]}

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

  此外,向 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();
   }
  }

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

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

  作为实例,在 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();
   }
  }

时间: 2024-10-12 10:40:17

(转)Java调用SQL Server的存储过程详解的相关文章

Java调用SQL Server的存储过程详解

转载自Microsoft的官方文档 http://msdn2.microsoft.com/zh-cn/library/ms378995.aspx收录于 www.enjoyjava.net/f25 本文较长,包含了如下几部分 使用不带参数的存储过程 使用带有输入参数的存储过程 使用带有输出参数的存储过程 使用带有返回状态的存储过程 使用带有更新计数的存储过程 1使用不带参数的存储过程 使用 JDBC 驱动程序调用不带参数的存储过程时,必须使用 call SQL 转义序列.不带参数的 call 转义

Java调用SQL Server的存储过程详解(转)

1使用不带参数的存储过程 使用 JDBC 驱动程序调用不带参数的存储过程时,必须使用 call SQL 转义序列.不带参数的 call 转义序列的语法如下所示: 以下是引用片段:{call procedure-name} 作为实例,在 SQL Server 2005 AdventureWorks 示例数据库中创建以下存储过程: 以下是引用片段:CREATE PROCEDURE GetContactFormalNames  AS  BEGIN   SELECT TOP 10 Title + ' '

SQL Server:触发器详解

SQL Server:触发器详解 1. 概述 2. 触发器的分类 3. Inserted和Deleted表 4. 触发器的执行过程 5. 创建触发器 6. 修改触发器: 7. 删除触发器: 8. 查看数据库中已有触发器: 9. “Instead of”相关示例: 10. “After”触发器 11. 参考资源 1. 概述 触发器是一种特殊的存储过程,它不能被显式地调用,而是在往表中插入记录﹑更新记录或者删除记录时被自动地激活. 所以触发器可以用来实现对表实施复杂的完整性约束. 2. 触发器的分类

Java调用SMSLib发送短信详解

项目中需要用到发送短信功能,之前没做过这方面,找人咨询了一下,也网上查了查,发现并不是很复杂.目前项目已经完成了,做个记录以备后用.程序中发送短信主要有4种方法: 1.向当地的运营商申请网关,不需要额外的设备,利用对方提供的 API调用程序发送短信,适用于大型的通信公司.稳定,速度快,适合短信量特别大的需求,需要连接到运营商的网络中,不适合内网项目. 2.短信猫发送短信,借助像 GSM MODEM之类的设备(支持AT指令的手机也行),通过数据线连接电脑来发送短信,这种方法比较适用于小公司及个人.

JDBC连接SQL Server 2005步骤详解

一.设置SQL Server服务器:    1."开始" → "程序" → "Microsoft SQL Server 2005" → "配置工具" → "SQL Server Configuration Manager"(确认"SQL Server Management Studio"已关闭)    2."SQL Server 2005 服务"中停止服务"

SQL Server表分区详解

原文:SQL Server表分区详解 什么是表分区 一般情况下,我们建立数据库表时,表数据都存放在一个文件里. 但是如果是分区表的话,表数据就会按照你指定的规则分放到不同的文件里,把一个大的数据文件拆分为多个小文件,还可以把这些小文件放在不同的磁盘下由多个cpu进行处理.这样文件的大小随着拆分而减小,还得到硬件系统的加强,自然对我们操作数据是大大有利的. 所以大数据量的数据表,对分区的需要还是必要的,因为它可以提高select效率,还可以对历史数据经行区分存档等.但是数据量少的数据就不要凑这个热

SQL Server with(nolock)详解

原文:SQL Server with(nolock)详解 大家在写查询时,为了性能,往往会在表后面加一个nolock,或者是with(nolock),其目的就是查询是不锁定表,从而达到提高查询速度的目的. 什么是并发访问:同一时间有多个用户访问同一资源,并发用户中如果有用户对资源做了修改,此时就会对其它用户产生某些不利的影响,例如: 1:脏读,一个用户对一个资源做了修改,此时另外一个用户正好读取了这条被修改的记录,然后,第一个用户放弃修改,数据回到修改之前,这两个不同的结果就是脏读. 2:不可重

(转)jdbc 调用 sql server 的存储过程时“该语句没有返回结果集”的解决方法

本文转载自:http://hedyn.iteye.com/blog/856040 在JDBC中调用SQL Server中的存储过程时出现如下异常: com.microsoft.sqlserver.jdbc.SQLServerException: 该语句没有返回结果集. at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:171) at com.microsof

c++ builder调用sql server的存储过程进行数据的下载和上传

小小的几行代码,在这里搞了一天.好好的一个周六过的无比的难受.代码很简单,但是主要原因是因为在用合作商的软件上传数据的时候有些框框没有勾选. come on....... 1.用两个控件ADOConnection.ADOStoredProc. 1.1 用ADOStoredProc的connection关联到ADOConnection   1.2 ADOConnection连接sql server数据库(两种方式.我在这用的代码连接的,这样比较灵活.另一种方式比简单.不会可以问我,联系方式在下面)