《數據庫系統概念》7-函數、存儲過程、觸發器

1、函數和存儲過程
a)經過函數和存儲過程能夠將業務邏輯保存在數據庫,在須要的時候調用。好比學生在一個學期能夠修的最大課程數、導師的最小授課數等,這些判斷具備比較複雜的邏輯,雖然在數據庫外也能夠實現這樣的控制,但用函數或存儲過程在數據庫的入口來把關,能夠與應用程序獨立開來,便於維護。但感受將業務邏輯獨立寫在存儲過程也不必定就能便於維護。
b)SQL標準規定的函數定義方法爲:
create function dept count(dept_name varchar(20))
returns integer
begin
declare d_count integer;
select count(*) into d_count
from instructor
where instructor.dept_name= dept_name
return d count;
end
函數定義好後,能夠在查詢語句中調用,就像內置函數同樣:
select dept name, budget
from instructor
where dept count(dept name) > 12;
c)函數還能夠返回表,稱爲表函數(table functions),這至關於帶參數的視圖
create function instructors of (dept_name varchar(20))
returns table ( ID varchar (5), name varchar (20), dept_name varchar (20), salary numeric (8,2))
return table
(select ID, name, dept_name, salary
from instructor
where instructor.dept_name = instructor of.dept_name);
相似的功能也可使用存儲過程:
create procedure dept_count_proc(in dept_name varchar(20), out d_count integer) begin select count(*) into d_count
from instructor
where instructor.dept_name= dept_count proc.dept_name
end
in和out表示數據的輸入輸出。存儲過程還能夠重載。
d)存儲過程和函數的區別:
函數只能經過return語句返回單個值或者表對象。而存儲過程不容許執行return,可是經過out參數返回多個值;
函數是能夠嵌入在sql中使用的,能夠在select中調用,而存儲過程不行;
函數限制比較多,好比不能用臨時表,只能用表變量.還有一些函數都不可用等等.而存儲過程的限制相對就比較少;
通常來講,存儲過程實現的功能要複雜一點,而函數的實現的功能針對性比較強。

2、SQL的語法結構
a)SQL也像Java、C等語言同樣支持if、for等語法結構,用declare聲明變量、用set賦值,但一段SQL要寫在begin…end之間,使用begin atomic…end的話,內部的語句構成一個事務。
b)while和repeat
while boolean expression do
sequence of statements;
end while

repeat
sequence of statements;
until boolean expression
end repeat

c)for
declare n integer default 0;
for r as
select budget from department where dept name = ‘Music‘
do
set n = n− r.budget
end for

d)if
if boolean expression
then statement or compound statement
elseif boolean expression
then statement or compound statement else statement or compound statement
end if

3、觸發器Trigger
a)觸發器包含兩個要素:被觸發的時機、被觸發後執行的動做。
在數據庫自帶的一致性約束機制沒法知足業務需求時,能夠用觸發器來限制;也能夠實現監控、報警、自動化等需求。
b)觸發器的建立
create trigger timeslot_check1 after insert on section
referencing new row as nrow
for each row
when (nrow.time slot_id not in (
select time slot_id
from time_slot))
begin
rollback
end;
爲在section表insert時建立的觸發器,referencing new row as nrow會將被插入的行保存到nrow臨時變量,而後使用for each row來遍歷。
除了插入操做,刪除的觸發器寫法爲:
create trigger timeslot_check2 after delete on timeslot
referencing old row as orow
for each row
when (orow.time slot_id not in (
select time slot_id
from time_slot)
and orow.time slot_id in (
select time slot_id from section)) begin
rollback
end;
臨時保存的是刪除前的舊行,那麼update時新行、舊行都須要:
create trigger credits_earned after update of takes on (grade)
referencing new row as nrow
referencing old row as orow
for each row
when …
begin atomic

end;
只有takes.grade被更新時纔會被觸發
c)除了用after定義動做發生後的觸發器,還可使用before在動做發生前觸發;除了針對行的觸發器(for each row),還有針對表的觸發器,對應的語法有;refenencing old/new table as、for each statement
d)觸發器雖然能夠用來解決不少問題,但若是有替代方法,便不推薦使用觸發器,由於觸發器的錯誤只能在運行時發現,並且多個觸發器的關聯會形成維護的困難。


學習資料:Database System Concepts, by Abraham Silberschatz, Henry F.Korth, S.Sudarshan​sql

相關文章
相關標籤/搜索