首先介紹一下什麼是存儲過程:存儲過程就是將常用的或很複雜的工作,預先用SQL語句寫好並用一個指定的名稱存儲起來,並且這樣的語句是放在數據庫中的,還可以根據條件執行不同SQL語句, 那麼以後要叫數據庫提供與已定義好的存儲過程的功能相同的服務時,只需調用execute,即可自動完成命令。
請大家來了解一下存儲過程的語法。
Create PROC [ EDURE ] procedure_name [ ; number ]
[ { @parameter data_type }
[ VARYING ] [ = default ] [ OUTPUT ]
] [ ,...n ]
[ WITH
{ RECOMPILE | ENCRYPTION | RECOMPILE , ENCRYPTION } ]
[ FOR REPLICATION ]
AS sql_statement [ ...n ]
一、參數簡介
procedure_name
新存儲過程的名稱。過程名必須符合標識符規則,且對於數據庫及其所有者必須唯一。
要創建局部臨時過程,可以在 procedure_name 前面加一個編號符 (#procedure_name),要創建全局臨時過程,可以在 procedure_name 前面加兩個編號符 (##procedure_name)。完整的名稱(包括 # 或 ##)不能超過 128 個字符。指定過程所有者的名稱是可選的。
;number
是可選的整數,用來對同名的過程分組,以便用一條 Drop PROCEDURE 語句即可將同組的過程一起除去。例如,名爲 orders 的應用程序使用的過程可以命名爲 orderproc;1、orderproc;2 等。Drop PROCEDURE orderproc 語句將除去整個組。如果名稱中包含定界標識符,則數字不應包含在標識符中,只應在 procedure_name 前後使用適當的定界符。
@parameter
過程中的參數。在 Create PROCEDURE 語句中可以聲明一個或多個參數。用戶必須在執行過程時提供每個所聲明參數的值(除非定義了該參數的默認值)。存儲過程最多可以有 2100 個參數。
使用@符號作爲第一個字符來指定參數名稱。參數名稱必須符合標識符的規則。每個過程的參數僅用於該過程本身;相同的參數名稱可以用在其它過程中。默認情況下,參數只能代替常量,而不能用於代替表名、列名或其它數據庫對象的名稱。
data_type
參數的數據類型。所有數據類型(包括 text、ntext 和 image)均可以用作存儲過程的參數。不過,cursor 數據類型只能用於 OUTPUT 參數。如果指定的數據類型爲 cursor,也必須同時指定 VARYING 和 OUTPUT 關鍵字。
說明:對於可以是cursor 數據類型的輸出參數,沒有最大數目的限制。
VARYING
指定作爲輸出參數支持的結果集(由存儲過程動態構造,內容可以變化)。僅適用於遊標參數。
default
參數的默認值。如果定義了默認值,不必指定該參數的值即可執行過程。默認值必須是常量或 NULL。如果過程將對該參數使用 LIKE 關鍵字,那麼默認值中可以包含通配符(%、_、[] 和 [^])。
OUTPUT
表明參數是返回參數。該選項的值可以返回給 EXEC[UTE]。使用 OUTPUT 參數可將信息返回給調用過程。Text、ntext 和 image 參數可用作 OUTPUT 參數。使用 OUTPUT 關鍵字的輸出參數可以是遊標佔位符。
n
表示最多可以指定 2100 個參數的佔位符。
{RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
RECOMPILE 表明 SQL Server 不會緩存該過程的計劃,該過程將在運行時重新編譯。在使用非典型值或臨時值而不希望覆蓋緩存在內存中的執行計劃時,請使用 RECOMPILE 選項。
ENCRYPTION 表示 SQL Server 加密 syscomments 表中包含 Create PROCEDURE 語句文本的條目。使用 ENCRYPTION 可防止將過程作爲 SQL Server 複製的一部分發布。
說明:在升級過程中,SQL Server 利用存儲在 syscomments 中的加密註釋來重新創建加密過程。
FOR REPLICATION
指定不能在訂閱服務器上執行爲複製創建的存儲過程。.使用 FOR REPLICATION 選項創建的存儲過程可用作存儲過程篩選,且只能在複製過程中執行。本選項不能和 WITH RECOMPILE 選項一起使用。
AS
指定過程要執行的操作。
sql_statement
過程中要包含的任意數目和類型的 Transact-SQL 語句。但有一些限制。
n
是表示此過程可以包含多條 Transact-SQL 語句的佔位符。
註釋
/*和*/之間的爲註釋,可以包含一行和多行的說明文字。
其他說明
存儲過程的最大大小爲 128 MB。
二、存儲過程的優點都有哪些呢?
1.存儲過程只在創造時進行編譯即可,以後每次執行存儲過程都不需再重新編譯,而我們通常使用的SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。
2.經常會遇到複雜的業務邏輯和對數據庫的操作,這個時候就會用SP來封裝數據庫操作。當對數據庫進行復雜操作時(如對多個表進行Update,Insert,Query,Delete時),可將此複雜操作用存儲過程封裝起來與數據庫提供的事務處理結合一起使用。可以極大的提高數據庫的使用效率,減少程序的執行時間,這一點在較大數據量的數據庫的操作中是非常重要的。在代碼上看,SQL語句和程序代碼語句的分離,可以提高程序代碼的可讀性。
3.存儲過程可以設置參數,可以根據傳入參數的不同重複使用同一個存儲過程,從而高效的提高代碼的優化率和可讀性。
4.安全性高,可設定只有某此用戶才具有對指定存儲過程的使用權存儲過程的種類:
(1)系統存儲過程:以sp_開頭,用來進行系統的各項設定.取得信息.相關管理工作,如 sp_help就是取得指定對象的相關信息。
(2)擴展存儲過程 以XP_開頭,用來調用操作系統提供的功能exec master..xp_cmdshell 'ping 10.8.16.1'
(3)用戶自定義的存儲過程,這是我們所指的存儲過程常用格式
模版:Create procedure procedue_name [@parameter data_type][output][with]{recompile|encryption} as sql_statement
解釋:output:表示此參數是可傳回的
with {recompile|encryption} recompile:表示每次執行此存儲過程時都重新編譯一次;encryption:所創建的存儲過程的內容會被加密。
三、實例講解
實例1:只返回單一記錄集的存儲過程。
要求1:查詢表bankMoney的內容的存儲過程
create procedure sp_query_bankMoney
as
select * from bankMoney
go
exec sp_query_bankMoney
注* 在使用過程中只需要把中的SQL語句替換爲存儲過程名,就可以了很方便吧!
實例2(向存儲過程中傳遞參數):
加入一筆記錄到表bankMoney,並查詢此表中userID= Zhangsan的所有存款的總金額。
Create proc insert_bank @param1 char(10),@param2 varchar(20),@param3 varchar(20),@param4 int,@param5 int output
with encryption ---------加密
as
insert bankMoney (id,userID,sex,Money) Values(@param1,@param2,@param3, @param4)
select @param5=sum(Money) from bankMoney where userID='Zhangsan'
go
在SQL Server查詢分析器中執行該存儲過程的方法是:
declare @total_price int
exec insert_bank '004','Zhangsan','男',100,@total_price output
print '總餘額爲'+convert(varchar,@total_price)
go
在這裏再囉嗦一下存儲過程的3種傳回值(方便正在看這個例子的朋友不用再去查看語法內容):
1.以Return傳回整數
2.以output格式傳回參數
3.Recordset
傳回值的區別:
output和return都可在批次程式中用變量接收,而recordset則傳回到執行批次的客戶端中。
實例3:使用帶有複雜 Select 語句的簡單過程
下面的存儲過程從四個表的聯接中返回所有作者(提供了姓名)、出版的書籍以及出版社。該存儲過程不使用任何參數。
USE pubs
IF EXISTS (Select name FROM sysobjects
Where name = 'au_info_all' AND type = 'P')
Drop PROCEDURE au_info_all
GO
Create PROCEDURE au_info_all
AS
Select au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
GO
au_info_all 存儲過程可以通過以下方法執行:
EXECUTE au_info_all
-- or
EXEC au_info_all
如果該過程是批處理中的第一條語句,則可使用:
au_info_all
實例4:使用帶有參數的簡單過程
Create PROCEDURE au_info
@lastname varchar(40),
@firstname varchar(20)
AS
Select au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
Where au_fname = @firstname
AND au_lname = @lastname
GO
au_info 存儲過程可以通過以下方法執行:
EXECUTE au_info 'Dull', 'Ann'
-- or
EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
-- or
EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
-- or
EXEC au_info 'Dull', 'Ann'
-- or
EXEC au_info @lastname = 'Dull', @firstname = 'Ann'
-- or
EXEC au_info @firstname = 'Ann', @lastname = 'Dull'
如果該過程是批處理中的第一條語句,則可使用:
au_info 'Dull', 'Ann'
-- or
au_info @lastname = 'Dull', @firstname = 'Ann'
-- or
au_info @firstname = 'Ann', @lastname = 'Dull'
實例5:使用帶有通配符參數的簡單過程
Create PROCEDURE au_info2
@lastname varchar(30) = 'D%',
@firstname varchar(18) = '%'
AS
Select au_lname, au_fname, title, pub_name
FROM authors a INNER JOIN titleauthor ta
ON a.au_id = ta.au_id INNER JOIN titles t
ON t.title_id = ta.title_id INNER JOIN publishers p
ON t.pub_id = p.pub_id
Where au_fname LIKE @firstname
AND au_lname LIKE @lastname
GO
au_info2 存儲過程可以用多種組合執行。下面只列出了部分組合:
EXECUTE au_info2
-- or
EXECUTE au_info2 'Wh%'
-- or
EXECUTE au_info2 @firstname = 'A%'
-- or
EXECUTE au_info2 '[CK]ars[OE]n'
-- or
EXECUTE au_info2 'Hunter', 'Sheryl'
-- or
EXECUTE au_info2 'H%', 'S%'