MySQL、Oracle等主流關系型數據庫基本都支持存儲過程,這里使用Sql Server為例進行說明。
存儲過程的概念:Sql Server存儲過程
SQL Server 中的存儲過程是由一個或多個 Transact-SQL 語句或對 Microsoft .NET Framework 公共語言運行時 (CLR) 方法的引用構成的一個組。 簡單的說,非常類似與java中的方法,實質就是部署在數據庫端的一組定義代碼以及SQL。
存儲過程的作用(優點):1.代碼的重復使用
任何重復的數據庫操作的代碼都非常適合于在過程中進行封裝。 這消除了不必要地重復編寫相同的代碼、降低了代碼不一致性,并且允許擁有所需權限的任何用戶或應用程序訪問和執行代碼。
2.更強的安全性
多個用戶和客戶端程序可以通過過程對基礎數據庫對象執行操作,即使用戶和程序對這些基礎對象沒有直接權限。 過程控制執行哪些進程和活動,并且保護基礎數據庫對象。 這消除在了單獨的對象級別授予權限的要求,并且簡化了安全層。
3.更容易維護
在客戶端應用程序調用過程并且將數據庫操作保持在數據層中時,對于基礎數據庫中的任何更改,只有過程是必須更新的。 應用程序層保持獨立,并且不必知道對數據庫布局、關系或進程的任何更改的情況。
4.改進的性能
默認情況下,在首次執行過程時將編譯過程,并且創建一個執行計劃,供以后的執行重復使用。 因為查詢處理器不必創建新計劃,所以,它通常用更少的時間來處理過程。
5.減少了服務器/客戶端網絡流量
過程中的命令作為代碼的單個批處理執行。 這可以顯著減少服務器和客戶端之間的網絡流量,因為只有對執行過程的調用才會跨網絡發送。 如果沒有過程提供的代碼封裝,每個單獨的代碼行都不得不跨網絡發送。
可以類比成java中的基礎類庫。總之就是高性能、安全、復用、易維護。
存儲過程的類型:1.用戶定義
用戶定義的過程可在用戶定義的數據庫中創建,或者在除了 Resource 數據庫之外的所有系統數據庫中創建。
2.臨時
臨時過程是用戶定義過程的一種形式。 臨時過程與永久過程相似,只是臨時過程存儲于 tempdb 中。
3.系統
系統過程是 SQL Server 隨附的。 它們物理上存儲在內部隱藏的 Resource 數據庫中,但邏輯上出現在每個系統定義數據庫和用戶定義數據庫的 sys 架構中。
4.擴展的用戶定義過程(DePRecated,將被CLR存儲過程替代,以后再專門開貼)
通過擴展的過程,可以使用 Java 之類的編程語言創建外部例程。 這些過程是 SQL Server 實例可以動態加載和運行的 DLL。
創建表(Sql Server 2005)CREATE TABLE [user](userId int,userName NVARCHAR[20],passWord NVARCHAR[20]);
3. 再隨便填入一些數據。
4. 打開查詢分析器,創建存儲過程,如圖。
先來看一個簡單的存儲過程定義(我個人認為先看實例,再看語法是最好的學習方式,因為一開始上來就看語法,會讓人摸不著北):
1.不帶參數存儲過程Name = select_del,獲取user表中的全部記錄。
1 CREATE PROCEDURE proc_select_user2 AS3 BEGIN4 SELECT * FROM [user]5 END6 GO
執行:
EXECUTE proc_select_user;2.帶輸入參數
存儲過程Name = proc_find_by_id_range,獲取user表中Id在給定范圍內的所有記錄。
1 CREATE PROCEDURE proc_find_by_id_range(@startId INT, @endId INT)2 AS3 BEGIN4 SELECT * FROM [user] WHERE userId BETWEEN @startId AND @endId5 END6 GO
執行:
EXECUTE proc_find_by_id_range @startId = 10000,@endId = 10100;3.帶輸入輸出參數
存儲過程Name = proc_find_userName_by_id,通過id獲取userName。
1 CREATE PROCEDURE proc_find_userName_by_id 2 @userId INT, 3 @userName NVARCHAR(20) OUTPUT 4 AS 5 BEGIN 6 SELECT @userName = userName 7 FROM [user] 8 WHERE userId = @userId 9 END10 GO
執行:
1 DECLARE @userName NVARCHAR(20);2 EXECUTE proc_find_userName_by_id 10004,@userName OUTPUT;(這邊如果用@變量 = OUTPUT會報錯,所以換一種寫法)3 SELECT @userName as 'result';
存儲過程Name = proc_check_password_isnull,查詢某Id的用戶是否設了密碼。
1 CREATE PROCEDURE proc_check_password_isnull 2 @userId int 3 AS 4 BEGIN 5 IF(select password FROM [user] 6 WHERE userId = @userId) = null 7 RETURN 0 8 ELSE 9 RETURN 110 END11 GO
執行:
1 DECLARE @status int;2 EXECUTE @status = proc_check_password_isnull @userId = 10000;3 SELECT @status as 'result';
通過上面幾個例子基本上也能明白存儲過程的用法了,下面再給出存儲過程語法的定義:
1 --SQL Server Stored Procedure Syntax 2 CREATE { PROC | PROCEDURE } [schema_name.] procedure_name [ ; number ] 3 4 [ { @parameter [ type_schema_name. ] data_type } 5 [ VARYING ] [ = default ] [ OUT | OUTPUT | [READONLY] 6 ] [ ,...n ] 7 8 [ WITH <procedure_option> [ ,...n ] ] 9 [ FOR REPLICATION ]10 11 AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }12 13 [;]14 15 <procedure_option> ::=16 [ ENCRYPTION ]17 [ RECOMPILE ]18 [ EXECUTE AS Clause ]
其中大部分關鍵字都在上面的四個例子中出現過,也比較好理解,下面再解釋一些沒展示過的關鍵字:
1 [ WITH <procedure_option> [ ,...n ] ]2 <procedure_option> ::=3 [ ENCRYPTION ]4 [ RECOMPILE ]5 [ EXECUTE AS Clause ]
這個是可以為存儲過程定義一些特性,ENCRYPTION是可以為存儲過程加密,RECOMPILE是不緩存,每次調用存儲過程需要重新編譯,EXECUTE AS Clause是否作為語句塊執行。
[ FOR REPLICATION ]
指定不能在訂閱服務器上執行為復制創建的存儲過程。.使用 FOR REPLICATION 選項創建的存儲過程可用作存儲過程篩選,且只能在復制過程中執行。本選項不能和 WITH RECOMPILE 選項一起使用。
ELSE其實每個數據庫都有很多系統定義的存儲過程,如user表中的存儲過程:
如果有興趣可以去研究下系統的存儲過程,既可以熟練存儲過程的使用,也能對數據庫里面的機制理解的更深。
其實存儲過程中還有很多用法沒有介紹,如通配符、CLR、以及游標。以后如有時間再深入研究。有不對的地方,請大家指正:)
新聞熱點
疑難解答