存儲過程
存儲過程和函數類似於C語言裏的函數
在存儲過程中有輸入參數,輸出參數
共有三步:
- 創建存儲過程
- 執行存儲過程
- 刪除存儲過程
創建
create proc proc_name -- 創建執行過程的名字,proc 可以寫成procedure
@param1 type, -- 輸入參數,需要對應實參
@param2 type,
@param3 type out -- 輸出參數
as
begin
sql 執行體
end -- 輸入輸出參數都可以沒有
實例:查詢指定學號學生的平均成績,並將平均成績返回
create proc proc_avggrade
@sno varchar(10),
@savg int out -- 帶out的是相當於返回值
as
begin
select @savg = avg(grade)
from sc
where sno = @sno
end
執行
declare @param1 type, @param2 type, @param3 type
set @param1 = values1
set @param2 = valuse2
-- @params 沒賦值,因爲會被返回值覆蓋
exec proc_name @param1, @param2, @param3 out-- 對應創建的模板,輸入輸出實參也可以沒有(如果定義時候沒有的話)
select @param3 -- 查詢結果
實例:執行上面創建好的存儲過程
declare @sno varchar(10), @savg int
set @sno = '201215121'
exec proc_avggrade @sno, @savg -- exec可以寫成execute
select @savg -- 查看的話要寫這句查詢
刪除
drop procedure proc_name
實例:刪除上面的存儲過程
drop procedure proc_avggrade;
函數
函數分爲三種:
- 標量函數
- 內嵌表值函數
- 多語句表值函數
標量函數
即返回值是一個值
create function function_name(@param1,@param2)
returns type -- 注意是returns!!,後面跟一個類型 => 返回值類型
as
begin
sql 執行體
return val -- 返回一個具體值,要跟上面returns的返回類型對應
end
例子:
create function whichgeneration(@birthday datetime) -- 局部變量@開頭,要注意
returns varchar(12)
as
begin
if year(@birthday) < 1980 -- year取年份的函數
return "too old";
else if year(@birthday) < 1990
return "80s";
else
return "90s";
end
內嵌表值函數
返回值是張表
create function schema.func_name(@param1, @param2)
returns table -- 返回表
as
begin
sql 執行體
return select....
end0
例子:定義一個函數返回學生的姓名和學號
create function dbo.fun()
returns table
as -- 就一句話可以不寫begin end
return
select sno, sname
from student
多語句表值函數
不常用
觸發器
用戶定義在關係表上的一類由事件驅動的特殊過程
作用:
- 可以對數據庫進行級聯修改
- 實現比check更復雜的約束
- 比較數據修改前後的差別
- 強制表的修改要合乎業務規則
分類:
- delete觸發器
- insert觸發器
- update觸發器
每個觸發器都有兩個專用臨時表:
- inserted表
- deleted表
語法:
create trigger tri_name
on table_name
after/for/instead of update/delete/insert -- instead of是一起的,表示在操作之前執行,after和for是在執行之後執行
as
begin
sql執行過程
end
例如:使用delete觸發器
當刪除表student中的記錄時,自動刪除sc中對應學號的記錄
create trigger tr_student_sc_delete
on student -- 刪除student的數據,所以建立在student上
after delete -- 刪除之後才執行操作
as
begin
declare @sno char(10)
select @sno=deleted.sno -- 被刪除的數據會放再deleted表中
from delete
delete from sc
where sno = @sno
end
PS:當使用instead of時,會在執行操作前執行觸發器操作,並且相當於做了攔截,如果想繼續操作,需要在觸發器執行體中再寫一遍
可以使用回滾操作,rollback transaction,之前進行的操作會全部失效