當你還在使用拼接 T-SQL 語句讓后通過 SqlCommand 執行它,是否感覺過的很麻煩?或許T-SQL語句很簡單,也就花費不了多少時間。如果T-SQL語句長達5行以上你是否會感覺厭惡、頻繁出錯呢?而今天就讓我們去學習一個可以大大減少我們在VS中拼寫T-SQL語句的方法。就在是學習如何編寫和使用存儲過程。
所要具備的條件:
- 學習過 ADO.NET
- 學習過 T-SQL 基本語句
- 使用NORTHWND數據庫作為舉例
一、什么是存儲過程
很多權威的說法就是‘允許重復執行某個任何的SQL語句。只要創建某個過程一次,就可以在程序中多次重用它。這一稿了程序的可維護性,允許程序以統一、優化的方式訪問數據庫。’,當然我不知道大家有多少人可以完全的理解,所以這里我就是用比較簡單的方式來說明(只是個人暫時的理解): 就是一種寫好的T-SQL語句,但是卻封裝了這些T-SQL語句,跟函數一樣,可以允許我們傳入參數,返回參數(如果有記錄集還是一樣返回)。只是當我們使用的是查詢語句時比一般的函數多返回一個記錄集,其他的完全跟函數一樣。
優點:
- 在 SQL SERVER 中編寫,提示更佳
- 在 SQL SERVER 中可以立即進行測試
- 因為 存儲過程 存儲在數據庫中並經過優化,執行速度更快
- 大大節省我們在VS中編寫T-SQL語句的時間
缺點:
- 如果要修改,必須進入到數據庫中修改
- 需要記住每個存儲過程的調用名、參數、返回值以及功能
什么技術都會有缺點和優點,除非你的功能很簡單,否則選擇使用存儲過程優點還是很大的.我們可以單獨寫個各個存儲過程的說明
二、了解基本操作
- 如何聲明一個無參數無返回值的存儲過程
View Code
1 CREATE PROCEDURE sp_Select_All_Employees 2 AS 3 SELECT employeeid,firstname,lastname 4 FROM Employees 5 ORDER BY lastname , firstname
各部分說明如下:
CREATE PROCEDURE sp_Select_All_Employees /* 創建一個名為 sp_Select_All_Employees 的存儲過程 */
AS SELECT employeeid , firstname , lastname FROM employees ORDER BY lastname , firstname /* AS 后面為實現該存儲過程的功能語句 */
- 創建一個帶有一個參數的存儲過程
View Code
1 CREATE PROCEDURE sp_Orders_By_EmployeeId 2 @employeeid int 3 AS 4 SELECT orderid , customerid 5 FROM orders 6 WHERE employeeid = @employeeid 7 8 9 /* 10 其中 @employeeid 為輸入參數,且后面為該參數類型 11 */
- 創建帶有一個傳入參數、返回值和輸出參數的存儲過程
View Code
1 CREATE PROCEDURE sp_Orders_By_EmployeeId2 2 @employeeid int, 3 @ordercount int = 0 output 4 AS 5 SELECT orderid,customerid 6 FROM orders 7 WHERE employeeid = @employeeid; 8 SELECT @ordercount = count(*) 9 FROM orders 10 WHERE employeeid = @employeeid 11 return @ordercount
各部分說明如下:
1 @ordercount int = 0 output 2 --表示 @ordercount 變量為 int 類型,默認值為 0 且為輸出參數 3 4 return @ordercount 5 --表示 @ordercount 為返回值
- 修改存儲過程
ALTER PROCEDURE --存儲程序名稱 --改變的參數 AS --改變后的T-SQL語句
- 查看存儲過程
execute sp_helptext --存儲過程名稱
- 重命名存儲過程
EXECUTE sp_rename --需要改的存儲過程名稱 --改后的存儲過程名稱
- 調用存儲過程
這個調用和一般的調用函數一樣,只是需要在存儲過程名稱前加EXECUTE,其次沒有括號
類似如下:
EXECUTE sp_Orders_By_EmployeeId2 2 @value
三、在C#中使用存儲過程
1.調用 sp_Select_All_Employees
1 SqlConnection con = new SqlConnection('/*數據庫連接字符串*/'); 2 try 3 { 4 con.Open(); 5 SqlCommand cmd = con.CreateCommand(); 6 cmd.CommandType = CommandType.StoredProcedure; 7 cmd.CommandText = "sp_Select_All_Employees"; 8 SqlDataReader reader = cmd.ExecuteReader(); 9 /* 10 輸出數據或者下斷點看 11 */ 12 }
2.調用 sp_Orders_By_EmployeeId2
1 SqlConnection con = new SqlConnection("/*數據庫連接字符串*/"); 2 try 3 { 4 con.Open(); 5 SqlCommand cmd = con.CreateCommand(); 6 cmd.CommandType = CommandType.StoredProcedure; 7 cmd.CommandText = "sp_Orders_By_EmployeeId2"; 8 SqlParameter inparm = cmd.Parameters.Add("@employeeid",SqlDbType.Int); 9 inparm.Direction = ParameterDirection.Input; 10 inparm.Value = 2; 11 SqlParameter outparm = cmd.Parameters.Add( 12 "@ordercount",SqlDbType.Int); 13 outparm.Direction = ParameterDirection.Output; 14 SqlParameter retval = cmd.Parameters.Add( 15 "return_value",SqlDbType.Int); 16 retval.Direction = ParameterDirection.ReturnValue; 17 SqlDataReader reader = cmd.ExecuteReader(); 18 /* 19 同上 20 */ 21 }