Java调用SQL语法 Server的存储过程详解
1应用不带参数的存储过程
应用 JDBC 驱动程式调用不带参数的存储过程时,必需应用 call SQL语法 转义序列。不带参数的 call 转义序列的句子语法如下所示:
以下是引用片段:
{call procedure-name}
作为举例,在 SQL语法 Server 二零零五 AdventureWorks 示例数据库中创建以下存储过程:
以下是引用片段:
CREATE PROCEDURE ContactFormalNames
AS
BEGIN
SELECT TOP 10 Title + ' ' + FirstName + ' ' + LastName AS FormalName
FROM Person.Contact
END
此存储过程返回单个结果集,其中包含一列数据(由 Person.Contact 表中前十个请致电的称呼、名字和姓氏组成)。
在下面的举例中,将向此参数传递 AdventureWorks 示例数据库的打开连接,然后应用 executeQuery 技巧调用 ContactFormalNames 存储过程。
以下是引用片段:
public static void executeSprocNoParams(Connection con) ...{
try ...{
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("{call dbo.ContactFormalNames}");
while (rs.next()) ...{
System.out.println(rs.getString("FormalName"));
}
rs.close();
stmt.close();
}
catch (Exception e) ...{
e.printStackTrace();
}
}
2应用带有输入参数的存储过程
应用 JDBC 驱动程式调用带参数的存储过程时,必需结合 SQL语法ServerConnection 类的 prepareCall 技巧应用 call SQL语法 转义序列。带有 IN 参数的 call 转义序列的句子语法如下所示:
以下是引用片段:
{call procedure-name[([参数][,[参数]]...)]}
构造 call 转义序列时,请应用 ?(如何)char来指定 IN 参数。此char充当要传递给该存储过程的参数值的占位符。应用 SQL语法ServerPreparedStatement 类的 setter 技巧之一为参数指定值。可应用的 setter 技巧由 IN 参数的数据类别决定。
向 setter 技巧传递值时,不仅需求指定要在参数中应用的实际值,还必需指定参数在存储过程中的序数位置。例如,假如存储过程包含单个 IN 参数,则其序数值为 1。假如存储过程包含两个参数,则第一个的序数值为 1,第二个序数值为 2。
作为如何调用包含 IN 参数的存储过程的举例,应用 SQL语法 Server 二零零五 AdventureWorks 示例数据库中的 uspEmployeeManagers 存储过程。此存储过程接受名为 EmployeeID 的单个输入参数(它是一个的整数值),然后基于指定的 EmployeeID 返回受雇及其经理的递归列表。下面是调用此存储过程的 Java 代码:
以下是引用片段:
public static void executeSprocInParams(Connection con) ...{
try ...{
PreparedStatement pstmt = con.prepareStatement("{call dbo.uspEmployeeManagers(?)}");
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 驱动程式调用此类存储过程时,必需结合 SQL语法ServerConnection 类的 prepareCall 技巧应用 call SQL语法 转义序列。带有 OUT 参数的 call 转义序列的句子语法如下所示:
以下是引用片段:
{call procedure-name[([参数][,[参数]]...)]}
构造 call 转义序列时,请应用 ?(如何)char来指定 OUT 参数。此char充当要从该存储过程返回的参数值的占位符。要为 OUT 参数指定值,必需在运行存储过程前应用 SQL语法ServerCallableStatement 类的 registerOutParameter 技巧指定各参数的数据类别。
应用 registerOutParameter 技巧为 OUT 参数指定的值必需是 Java编程.sql.Types 所包含的 JDBC 数据类别之一,而它又被映射成本地 SQL语法 Server 数据类别之一。有关 JDBC 和 SQL语法 Server 数据类别的详细消息,请参阅了解 JDBC 驱动程式数据类别。
当您对于 OUT 参数向 registerOutParameter 技巧传递一个的值时,不仅必需指定要用于此参数的数据类别,而且必需在存储过程中指定此参数的序号位置或此参数的名字。例如,假如存储过程包含单个 OUT 参数,则其序数值为 1;假如存储过程包含两个参数,则第一个的序数值为 1,第二个序数值为 2。
作为举例,在 SQL语法 Server 二零零五 AdventureWorks 示例数据库中创建以下存储过程: 根据指定的整数 IN 参数 (employeeID),该存储过程也返回单个整数 OUT 参数 (managerID)。根据 HumanResources.Employee 表中包含的 EmployeeID,OUT 参数中返回的值为 ManagerID。
在下面的举例中,将向此参数传递 AdventureWorks 示例数据库的打开连接,然后应用 execute 技巧调用 ImmediateManager 存储过程:
以下是引用片段:
public static void executeStoredProcedure(Connection con) ...{
try ...{
CallableStatement cstmt = con.prepareCall("{call dbo.ImmediateManager(?, ?)}");
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 ImmediateManager
以下是引用片段:
@employeeID INT,
@managerID INT OUTPUT
AS
BEGIN
SELECT @managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = @employeeID
END
存储过程估计返回更新计数和多个结果集。Microsoft(微软) SQL语法 Server 二零零五 JDBC Driver 遵循 JDBC 3.0 规范,此规范规定在INDEX OUT 参数之前应INDEX多个结果集和更新计数。也那是说,实际运用程式应先INDEX所有 ResultSet object和更新计数,然后应用 CallableStatement.getter 技巧INDEX OUT 参数。否则,当INDEX OUT 参数时,尚未INDEX的 ResultSet object和更新计数将丢失。
4 应用带有返回状态的存储过程
应用 JDBC 驱动程式调用这种存储过程时,必需结合 SQL语法ServerConnection 类的 prepareCall 技巧应用 call SQL语法 转义序列。返回状态参数的 call 转义序列的句子语法如下所示:
以下是引用片段:
{[?=]call procedure-name[([参数][,[参数]]...)]}
构造 call 转义序列时,请应用 ?(如何)char来指定返回状态参数。此char充当要从该存储过程返回的参数值的占位符。要为返回状态参数指定值,必需在运行存储过程前应用 SQL语法ServerCallableStatement 类的 registerOutParameter 技巧指定参数的数据类别。
此外,向 registerOutParameter 技巧传递返回状态参数值时,不仅需求指定要应用的参数的数据类别,还必需指定参数在存储过程中的序数位置。对于返回状态参数,其序数位置始终为 1,这是由于它始终是调用存储过程时的第一个的参数。尽管 SQL语法ServerCallableStatement 类支持应用参数的名字来指示特定参数,但您只能对返回状态参数应用参数的序号位置编号。
作为举例,在 SQL语法 Server 二零零五 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 应用带有更新计数的存储过程
应用 SQL语法ServerCallableStatement 类构建对存储过程的调用之后,应用 execute 或 execute更新 技巧中的任意一个的来调用此存储过程。execute更新 技巧将返回一个的 int 值,该值包含受此存储过程效果的行数,但 execute 技巧不返回此值。假如应用 execute 技巧,并且期望获得受效果的行数计数,则在运行存储过程后调用 get更新Count 技巧。
作为举例,在 SQL语法 Server 二零零五 AdventureWorks 示例数据库中创建以下表和存储过程:
以下是引用片段:
CREATE TABLE TestTable
(Col1 int IDENTitY,
Col2 varchar(50),
Col3 int);
CREATE PROCEDURE 更新TestTable
@Col2 varchar(50),
@Col3 int AS
BEGIN
UPDATE TestTable
SET Col2 = @Col2, Col3 = @Col3
END;
在下面的举例中,将向此参数传递 AdventureWorks 示例数据库的打开连接,并应用 execute 技巧调用 更新TestTable 存储过程,然后应用 get更新Count 技巧返回受存储过程效果的行计数。
以下是引用片段:
public static void execute更新StoredProcedure(Connection con) ...{
try ...{
CallableStatement cstmt = con.prepareCall("{call dbo.更新TestTable(?, ?)}");
cstmt.setString(1, "A");
cstmt.setInt(2, 100);
cstmt.execute();
int count = cstmt.get更新Count();
cstmt.close();
System.out.println("ROWS AFFECTED: " + count);
}
catch (Exception e) ...{
e.printStackTrace();
}
}