談到存儲過程和觸發器,沒有開發經驗的小鳥們,會認為存儲過程和觸發器是是很高深的內容。那么今天我就帶着大家一起來認識SQL Server中的這兩位重量級嘉賓。其實個人以為,盡量少用或者規避存儲過程和觸發器。
在學習存儲過程之前,我們先來討論下為什么需要存儲過程。
為什么需要存儲過程
當今的軟件大都應用於網絡中,而一般應用程序所需數據都保存在數據庫中。在沒有使用存儲過程的數據庫應用程序中,用戶所編寫的應用程序都是從本地計算機(client)向服務器(server)端發送SQL代碼來請求對數據庫中數據的增刪改差操作,服務器對接收到的SQL代碼進行編譯后執行,並將結果返回給client,再由客戶端的軟件處理后輸出。如果開發者對服務器安全性考慮不周全,就會為黑客提供盜取數據的機會。其中SQL注入是一種常見的方式。
為了防止SQL注入過程泄露企業的商業機密,我們可以通過存儲過程把對數據庫操作的SQL代碼預先編譯好並保存在服務器端。這樣既減少了網絡傳輸量,又能保證應用程序的運行性能。
然后,我們來看下什么是存儲過程
什么是存儲過程
存儲過程(procedure)類似於C#語言中的方法,它是SQL語句和控制語句的預編譯集合。存儲過程保存在數據庫里,可由應用程序調用執行。
說的簡單一點,存儲過程就像數據庫中運行的方法
存儲過程的優點:
- 執行速度更快---因為存儲過程是預編譯過的
- 模塊化程序設計—類似方法的復用
- 提高系統的安全性—防止SQL注入
- 減少網絡流量—只需傳輸存儲過程的名稱即可
存儲過程分類:
系統存儲過程:
系統存儲過程提供了管理數據和更新表的機制,並充當從系統表中檢索信息的快捷方式。
常用系統存儲過程:
用戶自定義存儲過程:
除了使用系統存儲過程外,用戶還可以創建自己的存儲過程。
常見存儲過程的語法:
CREATE PROC[EDURE] 存儲過程名
@參數1 數據類型 = 默認值 OUTPUT,
@參數n 數據類型 = 默認值 OUTPUT
AS
SQL語句
參數說明:
- 參數可選
- 參數分為輸入參數、輸出參數
- 輸入參數允許有默認值
如何執行存儲過程
EXEC 過程名 [參數]
這里提示一點:如果存儲過程存在輸出參數,一定要寫Exec
說了這么多,下面我們一起來寫一個分頁的存儲過程
create proc GetPageList
@pageIndex int,--頁碼
@pageSize int,--頁容量(每頁顯示幾條記錄)
@pageCount int output,--總頁數
@rowCount float output--總行數
as
select * from
(
select ROW_NUMBER() over(order by studentNo) as num,* from Student
) as temp where num between (@pageIndex-1)*@pageSize+1 and @pageIndex*@pageSize
select @rowCount=COUNT(*) from Student
set @pageCount=ceiling(@rowCount/@pageSize)
declare @pageCount int,@rowCount int
exec GetpageList 2,5,@pageCount output,@rowCount output
select @pageCount
select @rowCount
怎么樣,現在對存儲過程有點感覺了吧!
接下來咱們簡單看下觸發器的相關知識
觸發器
觸發器的作用:自動化操作,減少了手動操作以及出錯的幾率
觸發器是一種特殊類型的存儲過程,它不同於前面介紹的一般的存儲過程。一般的存儲過程名稱被直接調用,而觸發器主要是通過事件進行觸發而被執行
觸發器是一個功能強大的工具,在表中數據發生變化時自動強制執行。
一旦表 發生新增/修改/刪除 操作,那么就來自動執行一行代碼
常見的觸發器
DML觸發器:
Insert、delete、update(不支持select) 要執行的操作
After觸發器(for)、instead of觸發器(不支持before觸發器) 操作的時間(什么時候操作)
After(for):操作完成后才調用此觸發器
Instead of :操作完成前調用此觸發器
可以對一張表創建多個觸發器,但是一般不這樣用
注意:instead of替換新增語句的操作,之后新增操作不再更新到數據表。
如果向數據庫插入多條數據呢?
會觸發多次
After觸發器和instead of觸發器的器區別
After觸發器:
- 在語句執行完畢之后觸發
- 按語句觸發 ,而不是所影響的行數,無論影響多少行,只觸發一次。,
- 只能建立在常規表上,不能建立在視圖和臨時表上。
- 可以遞歸觸發,最高可達32級。
Instead of 觸發器
01,用來替換原來的操作
02,不會遞歸觸發
03,可以建在表和視圖上
指定執行觸發器而不是執行觸發 SQL 語句,從而替代觸發語句的操作。
Inserted表與deleted表
Inserted表只能用在觸發器中
Inserted 表包含新數據
Insert、update觸發器會用到
Deleted表包含舊數據
Delete、update觸發器會用到
常用語法
CREATE TRIGGER triggerName ON 表名
after(for)(for與after都表示after觸發器) | instead of
UPDATE|INSERT|DELETE(insert,update,delete)
AS
begin
…
end
接下來我們來看一個after觸發器的例子
--針對班級表的新增操作觸發器
create TRIGGER tg_grade ON grade
after-- after(操作完成后才調用此觸發器)
INSERT--UPDATE|INSERT|DELETE
AS
begin
--觸發器代碼
select * into studentbackup from inserted
--select * from inserted--保存了引發新增觸發器的新增數據,只能在觸發器中訪問
End
這個觸發器的作用:當向grade表中新增一條數據時,會將剛插入的數據備份到studentbackup中,其中studentbackup表必須不存在!
好了,今天存儲過程和觸發器的知識就介紹到這里。相信有了本的基礎,再去學習存儲過程和觸發器就異常簡單了