存儲過程是一組預先編輯好的SQL語句組成,編譯后存儲在數(shù)據(jù)庫中。
存儲過程可包含程序流、邏輯及對數(shù)據(jù)庫的查詢。它們可以接受參數(shù)、輸出參數(shù)、返回單個或者多個結果集及返回值。
存儲過程分三大類:用戶定義的存儲過程、擴展存儲過程、系統(tǒng)存儲過程。
一、用戶定義的存儲過程
該種存儲過程是指封裝了可重用代碼的模塊或者例程。存儲過程可以接受輸入?yún)?shù)、向客戶端返回表格或者標量結果和消息。調用數(shù)據(jù)定義語言(DDL)和數(shù)據(jù)操縱語言(DML)語句,然后返回輸出參數(shù)。創(chuàng)建自定義存儲過程時,存儲過程名前加上“##”表示創(chuàng)建了一個全局的臨時存儲過程;存儲過程名前加上“#”,表示創(chuàng)建的局部臨時存儲過程。局部臨時存儲過程只能在創(chuàng)建它的回話中使用,會話結束時,將被刪除。這兩種存儲過程都存儲在tempdb數(shù)據(jù)庫中。
用戶定義的存儲過程有兩種類型:T-SQL或者CLR.
T-SQL:存儲過程是指保存的T-SQL語句集合,可以接受和返回用戶提供的參數(shù)。例如,存儲過程中可能包含根據(jù)客戶端應用程序提供的信息在一個或者多個表中插入新行所需的語句。存儲過程也可能從數(shù)據(jù)庫向客戶端應用程序返回數(shù)據(jù)。
CLR: 存儲過程是指引用Microsoft.NET Framework公共語言的方法存儲過程,可以接受和返回用戶提供的參數(shù),它們在.NET Framework程序集是作為類的公共靜態(tài)方法實現(xiàn)的。
二、擴展存儲過程
擴展存儲過程允許使用編程語言(例如C)創(chuàng)建自己的外部例程。擴展存儲過程是以在SQL Server環(huán)境外執(zhí)行的動態(tài)連接(DLL文件)來實現(xiàn)的,可以加載到SQL Server實例運行的地址空間中執(zhí)行,擴展存儲過程可以用SQL Server擴展存儲過程API編程,擴展存儲過程以 前綴“xp_”來標識,對于用戶來說,擴展存儲過程和普通存儲過程一樣,可以用相同的方法來執(zhí)行。
三、系統(tǒng)存儲過程
系統(tǒng)存儲過程是SQL Server系統(tǒng)自身提供的存儲過程,可以作為命令執(zhí)行各種操作。
系統(tǒng)存儲過程主要用來從系統(tǒng)表中獲取信息,使用系統(tǒng)存儲過程完成數(shù)據(jù)庫服務器的管理工作,為系統(tǒng)管理員提供幫助,為用戶查看數(shù)據(jù)庫對象提供方便,系統(tǒng)存儲過程位于數(shù)據(jù)庫服務器中。例如,sys.sp_changedbowner 就是一個系統(tǒng)存儲過程。從物理意義上講,系統(tǒng)存儲過程存儲在源數(shù)據(jù)庫中,并以“sp_”開頭。從邏輯意義上來講,系統(tǒng)存儲過程出現(xiàn)在每個系統(tǒng)定義數(shù)據(jù)庫和用戶定義數(shù)據(jù)庫的sys構架中??蓪RANT、DENY 和REVOKE權限應用于系統(tǒng)存儲過程。


注意:雖然SQL Server 2008中的系統(tǒng)存儲過程被放在master數(shù)據(jù)庫中,但是仍可以在其他數(shù)據(jù)庫中對其進行調用,而且在調用時不必在存儲過程名前加上數(shù)據(jù)庫名。甚至當創(chuàng)建一個新數(shù)據(jù)庫時,一些系統(tǒng)存儲過程會在新數(shù)據(jù)庫中被自動創(chuàng)建。


例如:sp_databases --列出當前系統(tǒng)中的所有數(shù)據(jù)庫

例如:sp_renamedb ?--更改數(shù)據(jù)庫的名稱

如圖7,將原有的dataBase數(shù)據(jù)庫更改為Hotel數(shù)據(jù)庫。結果如圖8.


不帶參數(shù),直接寫數(shù)據(jù)庫名稱,如圖9

例如:sp_help --查看表中的所有信息

注意:如圖10,我們看到消息版中,告訴我們數(shù)據(jù)庫“master”中不存在或對于此操作無效,發(fā)現(xiàn)我們要查詢的表不在master數(shù)據(jù)庫中。如圖11:

以上是常用的系統(tǒng)存儲過程。
接下來,簡單說一下擴展存儲過程,如圖12.通過擴展存儲過程在D盤下創(chuàng)建myFile文件夾。

結果如下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 存儲過程的特點
接受輸入?yún)?shù)并以輸出參數(shù)的格式向調用過程或者批處理返回多個值。
包含用于在數(shù)據(jù)庫中執(zhí)行操作(包括調用其他過程)的編程語句。
向調用過程或者批處理返回狀態(tài)值,以指明成功或者失?。ㄒ约笆〉脑颍?。
存儲過程的優(yōu)點:
1、存儲過程加快系統(tǒng)運行速度,存儲過程在創(chuàng)建時已經(jīng)被編譯,以后每次執(zhí)行時不需要重新編譯。
2、存儲過程可以封裝復雜的數(shù)據(jù)庫操作,簡化操作流程,例如對多個表的更新,刪除等。
3、可實現(xiàn)模塊化的程序設計,存儲過程可以多次調用,提供統(tǒng)一的數(shù)據(jù)庫訪問接口,改進應用程序的可維護性。
4、存儲過程可以增加代碼的安全性,對于用戶不能直接操作存儲過程中引用的對象,SQL Server可以設定用戶對指定存儲過程的執(zhí)行權限。用戶只需提交存儲過程名稱就可以直接執(zhí)行,避免了攻擊者非法截取SQL代碼獲得用戶數(shù)據(jù)的可能性。
5、存儲過程可以降低網(wǎng)絡流量,存儲過程代碼直接存儲于數(shù)據(jù)庫中,在客戶端與服務器的通信過程中,不會產(chǎn)生大量的T-SQL代碼流量。一個需要數(shù)百行SQL語句代碼的操作可以通過一條執(zhí)行過程代碼來執(zhí)行,而不需要在網(wǎng)絡中發(fā)送數(shù)百行代碼
存儲過程的缺點:
1、數(shù)據(jù)庫移植不方便,存儲過程依賴與數(shù)據(jù)庫管理系統(tǒng),SQL Server存儲過程中封裝的操作代碼不能直接移植到其他的數(shù)據(jù)庫管理系統(tǒng)中。
2、不支持面向對象的設計,無法采用面向對象的方式將邏輯業(yè)務進行封裝,甚至形成通用的可支持服務的業(yè)務邏輯框架。
3、代碼可讀性差,不易維護。不支持集群。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 設計存儲過程
在創(chuàng)建存儲過程之前,必須先設計存儲過程。在設計存儲過程中,需要了解存儲過程的創(chuàng)建規(guī)則、存儲過程內部名稱以及加密過程等相關知識。
一、創(chuàng)建存儲過程的規(guī)則
(1)CREATE PROCEDURE定義自身可以包括任意數(shù)量和類型的SQL語句,但圖5中的語句除外。因為不能在存儲過程的任何位置使用這些語句。

(2)可以引用在同一存儲過程中創(chuàng)建的對象,只要引用時已經(jīng)創(chuàng)建了該對象即可。
(3)可以在存儲過程內引用臨時表。
(4)如果在存儲過程內創(chuàng)建本地臨時表,則臨時表僅為該存儲過程而存在;退出該存儲過程后,臨時表將消失。
(5)如果執(zhí)行的存儲過程將調用另一個存儲過程,則被調用的存儲過程可以訪問由第一個存儲過程創(chuàng)建的所有對象,包括臨時表在內。
(6)如果執(zhí)行對遠程Microsoft SQL Server 2008 實例進行更改的遠程存儲過程,則不能回滾這些更改。遠程存儲過程不參與事務處理。
(7)存儲過程中的參數(shù)的最大數(shù)目為2100.
(8)存儲過程中的局部變量的最大數(shù)目僅受可用內存的限制。
(9)根據(jù)可用內存的不同,存儲過程最大可達128MB。
二、限定存儲過程內的名稱
在存儲過程內,如果用于語句(例如SELECT、INSERT)的對象名沒有限定架構,則架構將默認為該存儲過程的架構。在存儲過程內,如果創(chuàng)建該存儲過程的用戶沒有限定SELECT、INSERT、UPDATE或者DELETE語句中引用的表名或者視圖名,則默認情況下,通過該存儲過程對這些表進行的訪問將受到該過程創(chuàng)建者的權限的限制。
三、加密存儲過程的定義
如果要創(chuàng)建存儲過程,并且希望確保其他用戶無法查看該過程的定義,則可以使用WITHENCRYPTION子句。這樣,過程定義將以不可讀的形式存儲。
注:存儲過程一旦被加密,其定義將無法解密,任何人(包括該存儲過程的所有者或者系統(tǒng)管理員)都將無法查看該存儲過程的定義。
創(chuàng)建存儲過程
創(chuàng)建不帶參數(shù)的存儲過程
CREATE PROC / PROCEDURE 存儲過程名 ? ? ?//存儲過程名稱在架構中必須是唯一的。
AS
? ? ?SQL語句
GO

創(chuàng)建帶參數(shù)的存儲過程
CREATE PROC / PROCEDURE 存儲過程名
? ? ? ?@參數(shù)1 ?數(shù)據(jù)類型=默認值,
? ? ? ?.......?
? ? ? ?@參數(shù)n ?數(shù)據(jù)類型=默認值?
AS
? ? SQL語句
GO

帶參數(shù)的存儲過程我們創(chuàng)建完成,刷新數(shù)據(jù)庫,就可以看到我們創(chuàng)建好的存儲過程。那么我們如何查詢執(zhí)行帶參數(shù)的存儲過程呢?
以上面的為例,第一種查詢執(zhí)行帶參數(shù)的存儲過程:如圖一17

第二種方式:如圖--18

第三種方式:--如圖19

這里我們需要注意的是:
上例結束時間我們設為默認default時,點擊執(zhí)行,消息版中報錯。顯示必須傳遞參數(shù)3。如果我們前面的參數(shù)是以@name=value的形式傳遞值的,那所有的參數(shù)都必須是這樣的形式來傳遞。如圖20

一般,操作最簡潔明了的是找到創(chuàng)建好的存儲過程,單擊右鍵-->執(zhí)行存儲過程

如圖22.可以在紅框內根據(jù)參數(shù),輸入想要查詢的存儲過程信息,點擊確定即可。
