亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java中調用SQL Server存儲過程詳解

2019-11-26 15:19:01
字體:
來源:轉載
供稿:網友

本文作者介紹了通過Java如何去調用SQL Server的存儲過程,詳解了5種不同的存儲。詳細請看下文

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 應用程序中使用命名參數。請注意,這些參數名稱對應于存儲過程的定義中的參數名稱: 11x16CREATE 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();

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久av久久久| 日本19禁啪啪免费观看www| 亚洲成人精品视频在线观看| 91av视频在线观看| 国内揄拍国内精品| 亚洲一区二区三区在线视频| 久久久亚洲国产| 欧美视频在线免费看| 国内精久久久久久久久久人| 日本在线精品视频| 激情av一区二区| 成人欧美一区二区三区黑人孕妇| 亚洲视频欧洲视频| 欧美极品在线播放| 4438全国亚洲精品在线观看视频| 欧美成年人视频网站| 国产+成+人+亚洲欧洲| 91免费精品视频| 亚洲电影成人av99爱色| 亚洲欧美日韩一区二区在线| 日韩视频第一页| 亚洲欧美日韩网| 国产综合在线观看视频| 欧美日韩亚洲一区二| 久久久久久久久亚洲| 一区二区三区亚洲| 欧美性理论片在线观看片免费| 亚洲天堂免费在线| 亚洲成成品网站| 成人福利在线视频| 国产一区二区三区在线观看视频| 欧美亚洲视频在线观看| 日韩hd视频在线观看| 国产成人av网| 国产精品午夜一区二区欲梦| 日韩久久免费电影| 一区二区三区 在线观看视| 亚洲久久久久久久久久久| 精品中文字幕在线2019| 久久精品国产电影| 久久久精品网站| 国产不卡av在线| 国产精品久久久久久久久久新婚| 亚洲精品在线视频| 日韩国产高清污视频在线观看| 日韩av在线高清| 欧美一区二区三区免费视| 亚洲免费人成在线视频观看| 国产精品视频中文字幕91| 色婷婷久久一区二区| 久久精品精品电影网| 97婷婷大伊香蕉精品视频| 91精品国产777在线观看| 亚洲在线视频观看| 日韩大片免费观看视频播放| 欧美一区二区视频97| 亚洲男人天天操| 亚洲成人av中文字幕| 国产精品自在线| 一本色道久久88综合日韩精品| 亚洲图片欧美日产| 88国产精品欧美一区二区三区| 欧美老妇交乱视频| 97精品国产91久久久久久| 中文字幕亚洲情99在线| 尤物tv国产一区| 亚洲一级片在线看| 性欧美在线看片a免费观看| 国产aⅴ夜夜欢一区二区三区| 岛国av一区二区在线在线观看| 91久久嫩草影院一区二区| 欧美激情国产日韩精品一区18| 亚洲国产精品久久久久秋霞蜜臀| 国产亚洲日本欧美韩国| 中文字幕日韩免费视频| 亚洲字幕在线观看| 麻豆国产精品va在线观看不卡| 欧美激情乱人伦一区| 欧美日韩免费在线| 日韩欧美在线第一页| 5566日本婷婷色中文字幕97| 性色av一区二区三区红粉影视| 久久手机免费视频| 日韩成人免费视频| 亚洲第一综合天堂另类专| 92版电视剧仙鹤神针在线观看| 欧美电影院免费观看| 91免费国产网站| 国产成人精品在线观看| 亚洲最大av在线| 欧美最顶级的aⅴ艳星| 亚洲激情视频在线观看| 影音先锋欧美在线资源| 亚洲欧美一区二区三区在线| 日韩在线观看精品| 精品视频9999| 亚洲性视频网站| 欧美性猛交xxxx黑人猛交| 欧美成人免费在线视频| 国产日韩欧美中文| 久久人人爽人人爽爽久久| 亚洲毛片在线观看.| 成人av色在线观看| 91禁国产网站| 欧美激情国内偷拍| 色偷偷噜噜噜亚洲男人| 久久久亚洲影院| 久久精品91久久久久久再现| 精品日韩中文字幕| 久久精品国产一区二区三区| 亚洲综合色av| 亚洲国产第一页| 中文字幕亚洲自拍| 日韩美女在线观看| 最新国产成人av网站网址麻豆| 国产成人福利夜色影视| 日韩精品一区二区视频| 亚洲欧美一区二区精品久久久| 国产成人高清激情视频在线观看| 欧美大片网站在线观看| 国产精品第100页| 一本色道久久综合亚洲精品小说| 色综合久久天天综线观看| 555www成人网| 日韩欧美在线字幕| 日韩av电影中文字幕| 亚洲人成电影网站色www| 久久久久久久亚洲精品| 精品国产精品自拍| 欧美多人爱爱视频网站| 亚洲欧美精品一区二区| 成人伊人精品色xxxx视频| 7m第一福利500精品视频| 欧美亚洲另类激情另类| 国产精品视频免费在线| 亚洲japanese制服美女| 日韩在线中文字幕| 91精品久久久久久久久久久| 国产一区二区免费| 欧美裸体男粗大视频在线观看| 成人精品视频久久久久| 国产精品自产拍在线观看中文| 欧美日韩国内自拍| 国产97色在线|日韩| 91亚洲国产成人精品性色| 国产精品稀缺呦系列在线| 日韩在线视频网站| 亚洲自拍小视频免费观看| 国产精品视频一区二区高潮| 国产精品九九九| 亚州成人av在线| 亚洲女人被黑人巨大进入| 欧美精品国产精品日韩精品| 奇米4444一区二区三区| 亚洲欧美色图片| 国产欧美一区二区三区久久人妖| 亚洲a级在线播放观看| 国产精品成熟老女人| 日本19禁啪啪免费观看www| 久久亚洲精品小早川怜子66| 亚洲欧美制服中文字幕| 91精品国产99| 久久久久中文字幕2018| 国产精品视频公开费视频|