1. 程式人生 > >SQL Server Transact-SQL程式設計/儲存過程/觸發器

SQL Server Transact-SQL程式設計/儲存過程/觸發器

1.T-sql語言
資料定義語言DDL對錶或檢視的操作
資料操縱語言DML對資料進行操作
資料控制語言
其他常用型別: 
    事務管理語言
    流程控制語言  迴圈  分支  選擇
    附加的語言元素     變數 常量
2.常量不需要宣告
全域性變數:一般系統生成
區域性變數:自己宣告的
declare @變數名 資料型別
set @變數名=值
select @變數名=表示式(表示式返回單個值)

declare @name nvachar(50)
set @name='張三'
select @name

--變數賦值方法二
select @name='王文'
select @name

3.
位運算子:&    |  ^ 
比較運算子: = <> != !< !> > >= < <=
邏輯運算子:
all如果一組的比較都為true則結果為true
and
any如果一組的比較中任何一個為true則結果為true
between
exists如果子查詢中包含了一些行,那麼結果為true
in
like
not
or
some 如果一組比較中,有些比較為true結果為true
賦值運算子=
連線運算子+
一元運算子
+正數
-負數
~返回數字的邏輯非
4.表示式
declare @str nvarchar(50)
select @str='姓名:'+姓名+‘性別:’+性別 from 學生資訊 where 學號=‘20050502’
select @str
5.註釋:變數說明、程式碼更改日期、演算法描述等
--單行註釋
/*多行註釋*/

6.
if bool表示式
begin 
語句塊
end
else
begin
語句塊
end

--語句塊包含多個語句時用begin  end 

declare @num int 
select @num=avg(分數) from 成績資訊 where 考試編號='0802' and課程編號='2'
if @num>80
begin
    print '這們課老師教課非常成功'
end
else
    print '這門課老師還需要繼續努力'
7.if  else 語句巢狀

declare @num int 
select @num=avg(分數) from 成績資訊 where 考試編號='0802' and課程編號='2'
if @num>=60
begin
    if @num<70
    print '成績剛剛及格,還要繼續努力'
    else if @num<80
    print '成績中等'
    else if @num<90
    print '成績良好'
    else
    print '成績優秀,希望把經驗分享給大家'
end
else
    print '這門課老師還需要繼續努力'

8.case語句
case 變量表達式
when  值1  then  操作語句1
when  值2  then  操作語句2
.
.
.
else 操作語句  --可以省略不設定
end

select  員工姓名 ,所任職位,員工職稱=
case 所任職位
when ‘經理’ then '高階職稱’
when ‘主管’ then '中級職稱'
when ‘職員’then '初級職稱'
else '其他職稱'
end 
from 員工資訊 

9.while 語句
while boolean表示式
begin
t-sql語句
break 
t-sql語句
continue
t-sql語句
end


declare @i int,@num int
set @i=1
set @num=1
while @i<=10
begin
    set @[email protected]*@i
    set @[email protected]+1
end
print @num

--FitemID,FParentID,FLevel  ID 父ID 級別

create function [dbo].[GetChild](@ID varchar(10))
return @t table (FitemID varchar(10),FParentID varchar(10),Level int)
as
begin
    declare @i int
    set @i=(select Flevel from department where [email protected]
    insert into @t select FitemID,FparentID,Flevel from department where [email protected]
 --當前級,本級,如果不要的話可以註釋掉  將當前級插入到表變數中
    while @@rowcount<>0  --全域性變數 @@rowcount執行sql語句受影響的行數
    begin
        set @[email protected]+1
        insert into @t
        select 
            a.FParentID=b.FitemID and [email protected]
    end
    return
end

create table department(
FitemID varchar(10),
FParentID varchar(10),
Fname varchar(50),
Flevel int
)

insert into department(FitemID,FParentID,FLevel)
values('1','0',1),
    ('2','1',2),
    ('3','1',2),
    ('4','1',2),
    ('5','2',3),
    ('6','2',3),
    ('7','2',3),
    ('8','3',3),
    ('10','3',3),
    ('11,'4',3),
    ('12','4',3),
    ('13','4',3),
    ('14','4',3),
    ('15','5',4),
    ('16','5',4),
    ('17','6',4),
    ('18','7',4)

select fITEMID from GETCHILD('2')


10. while 語句中使用其他語句
 3-100的素數
declare @i int
delcare @j int
set @i=3
while @i<=100
begin 
    declare @bol int
    set @bol=1
    SET @j=2
    begin
        while @j<sqrt(@i)
        begin
        if @i%@j=0
        begin
        set @bol=0
        break
        end
        set @[email protected]+1
    end
    if @bol=1 print @i
    set @[email protected]+1    
end

11.waitfor 延遲語句
waitfor {
delay time --延遲時間值
|time time --指定具體時間執行語句
}

--呼叫
waitfor delay '00:00:05'
exec sp_help

waitfor time '00:00:05'
exec sp_helpdb

12.goto 語句--跳轉語句

declare @Counter int 
set @Counter=1
while @Counter<10
begin
    print @Counter
    set @[email protected]+1
    if @Counter=4 goto Branch_One
    if @Counter=5 goto Branch_Two
end
Branch_One:
    print 'Jumping To_Branch One'
    goto Branch_Three;
Branch_Two:
    print 'Jumping To Branch Two'
Branch_Three:
    print 'Jumping To Branch Three'


13.try ...catch 錯誤處理語句

begin try 
sql 語句
end try 
bengin catch 
sql語句
end catch

begin try 
declare @num int 
set @num=1/0
select @num
end try 
begin catch
select error_line() as '錯誤行數',error_message() '錯誤訊息'
end catch

14.數學函式
abs 絕對值
exp 以E為底的指數
ceiling >=表示式的最小整數
floor <=表示式的最大整數
ln 數值表示式的自然對數
log 數值表示式以10為底的對
power 數值表示式進行冪運算的結果
round 舍入到指定長度或精度的數值表示式
sign 數值表示式的正號、負號、或零
square 數值表示式的平方
sqrt 數值表示式的平方根


declare @i float,@j int,@a decimal(18,2)
set @i=-12.345
set @j=100
print round(@i,2)
print floor(abs(round(@i,2)))
print power(@j,2)
print square(@j)
print power(@j,0.5)
print sqrt(@j)


15.字串函式
ascII 返回字串表示式中最左側的字元的ASCII程式碼值
char 返回指定ascII程式碼的字元
left 左子串函式,返回字串中從左邊開始指定個數的字串
len 返回指定字串表示式的字元數(不是位元組數),其中不包含尾隨空格
lower 轉換成小寫字元
ltrim刪除前導空格字串,返回刪除了前導空格之後的字元表示式
replace 替換函式 用第三個表示式替換第一個字串表示式中出現的所有第二個指定字串表示式的匹配項
replicate複製函式,以指定的次數重複字元表達
right 返回字串中從右邊開始指定個數的字元
rtrim刪除尾隨空格函式,刪除所有尾隨空格後返回一個字串
space 空格函式,返回由重複的空格組成的字串
str 數字向字元轉換函式,返回由數字資料轉換來的字元資料
substring 子串函式,返回字元表示式、二進位制表示式、文字表示式或影象表示式的一部分
upper 將小寫轉換為大寫

declare @str nvarchar(50)
set @str='hello word!'
print ascii(@str)
print char(104)
print left(@str,5) --hello
print right(@str,5) --orld!
print substring(@str,7,5) --world
print len(@str) --12長度

常用字串函式
charindex(父字串或列名錶達式,子字串)返回字串中某個指定的子串出現的開始位置,如果沒有發現子字串則返回0,此函式不可用於text 和 image資料型別
patindex('%子串%',列名)返回字串中某個指定的子串出現的位置,此函式可用於char、varchar和text資料型別

declare @str1 nvarchar(20),
@str2 nvarchar(20),
@str3 nvarchar(20),
@str4 nvarchar(20),
@str5 nvarchar(20),
set @str1='上海分公司經理'
set @str2='北京分公司經理'
set @str3='天津分公司經理'
set @str4='上海分公司財務經理'
set @str5='天津分公司財務經理'

--分公司經理
print charindex('分公司',@str4)
print right(@str1,len(@str1)-charindex('分公司',@str1)+1))
--分公司  經理
print right(@str1,len(@str1)-patinex('分公司%經理',@str1)+1))

16.聚合函式
AVG
COUNT
SUM
MAX
MIN

17.日期和時間函式
dateadd返回給指定日期加上一個時間間隔後的新datetime值  dateadd(間隔單位,間隔值,指定日期)
datediff返回跨兩個指定日期的日期邊界數和時間邊界數  datediff(單位,日期1,日期2)
datename返回指定日期的指定日期部分的字串
datepart返回表示指定日期的指定日期部分的整數 datepart(單位,指定日期)
day返回一個整數,表示指定日期的天DATEPART部分
getdate返回當前系統日期和時間
getutcdate返回當前的UTC時間
month放回表示指定日期的月部分的整數
year返回指定日期的年份

print getdate()
print getutcdate()
print year(getdate())
print month(getdate())
print day(getdate())
print datepart(year,getdate())
print datepart(day,getdate())
print datepart(yy,getdate())
print datepart(mm,getdate())
print datepart(dd,getdate())
print dateadd(mm,1,getdate())
print datediff(dd,'2018-01-01','2018-08-01')

18.標量值函式
create function 函式名
(@引數名  型別)
returns 返回值型別
[with encryption]加--密
begin
sql函式體
return  變量表達式
end

create function avgsum(@id varchar(10))
returns int
as 
begin
declare @sum int
select @sum=avg(分數) from 成績資訊
where 課程編號[email protected]
return @sum
end 
go

--呼叫函式
select dbo.avgsum('2');

19.表值函式
create function(@引數名 型別)
returns table
[with encryption]
[as]
return(sql語句返回資料表)


create function findcourse(@id varchar(10)) 
returns table
as
return
(    
select 課程名稱,姓名,分數,from(
    select b.課程名稱,c.姓名,avg(a.分數) 分數
    from 成績資訊 a join 課程資訊 b
    on a.課程編號=b.課程編號
    join 教師資訊 c on b.任課教師=c.教師編號
    where a.考試編號[email protected] 
    group by b.課程名稱,c.姓名
)a
where 分數>=85
)
go

--呼叫函式
select * from findcourse('0801')

20.遊標Cursor:是一種資料訪問機制,允許使用者訪問單獨的資料行,而不是對整個行集進行操作。使用者可以通過單獨處理每一行逐條收集資訊並對資料逐行進行操作,可以降低系統開銷和潛
在的阻隔情況,可以使用這些資料生成SQL程式碼並立即執行或輸出。
遊標主要包括兩部分:
    1)遊標結果集   由定義遊標的SELECT語句返回的行的集合
    2)遊標位置    指向這個結果集中的某一行的指標

特點:  返回一個完整的結果集,但允許程式設計語言只調用集合中的一行;
    允許定位在結果集的特定行;
    從結果集的當前位置檢索一行或多行;
    支援對結果集中當前位置的行進行資料修改;
    可以為其他使用者對顯示在結果集中的資料庫資料所做的更改提供不同級別的可見性支援;
    提供指令碼、儲存過程和觸發器中使用的訪問結果集中的資料的Q-SQL語句。
declare 遊標名稱 [insensitive][scroll] cursor --insensitive將結果集放到臨時表中游標操作的是臨時表中的資料,當資料庫中的資料更新時,遊標操作不受影響;scroll,沒有此關鍵
字遊標只能訪問結果集中下一行資料;當新增上此關鍵字時,可以訪問結果集中的第一行最後一行,上一行,下一行等操作,隨機指定遊標的位置
for select語句
[for {read only|update[of 列名1,列名2...列名n]}]  --read only只讀的遊標;update 可修改的遊標,當後面跟列名則指定只有那些列可以修改,若不寫列名則所有列都可以修改

declare student_cursor scroll cursor
for
select * from 學生資訊
for read only

deallocate student_cursor --釋放遊標

declare student_cursor scroll cursor
for
select * from 學生資訊
for update


--開啟遊標
open 遊標名稱
--檢索遊標
fetch [[next|prior|first|last|absolute{n |@nvar}|relative{n|@nvar}] --absolute指定檢索當前結果集中的第幾行,relative指定檢索在當前行向後幾行即間隔幾行去讀取
from]
遊標名
[into @variable_name]--將某一個數據行的列的值放到一個定義的變數中  
--關閉遊標
close 遊標名
--釋放遊標
deallocate 遊標名

--宣告遊標
declare stu_cursor scroll cursor for
select 姓名 from 學生資訊 

--開啟使用關閉釋放遊標
declare @NAME varchar(20)
open stu_cursor
--fetch next from stu_cursor 
--fetch first  from stu_cursor
fetch absolute(10)  from stu_cursor
into @NAME
print @name
close stu_cursor
deallocate stu_cursor

21.判斷遊標提取狀態
@@fetch_status --全域性變數獲取提取狀態
返回值:
0  fetch 語句成功
-1 fetch 語句失敗或行不在結果集中
-2 提取的行不存在

declare stu_cursor scroll cursor for
select 姓名 from 學生資訊

open stu_cursor
declare @name varchar(20)
--fetch last from stu_cursor
fetch next from stu_cursor
into @name
if @@fetch_status=0
print @name
else
print '提取資料錯誤'
close  stu_cursor

deallocate stu_cursor

22.遊標應用示例
--宣告一個遊標stu_cursor
declare stu_cursor scroll cursor for
select 學號 from 學生資訊

--建立一個臨時表#t
create table #t(name nvarchar(20),sorce int)
--開啟遊標
open stu_cursor
--宣告變數
delare @name varchar(20)
--檢索遊標
fetch next from stu_cursor
into @name
--while迴圈判斷檢索結果是否為0,檢索的遊標位置有沒有超出結果集的行
while @@fetch_status=0
begin
--如果fetch提前成功將當前行列的值放到臨時表#t中
insert into #t
select b.姓名,avg(分數) as 分數
from 成績資訊 a join 學生資訊 b
on a.學生編號=b.學號
where a.考試編號='0801' and b.學號[email protected]
group by b.姓名
/*
.
.此處可以查詢檢索很多資訊放到臨時表中,通過學號[email protected]檢索將不相關的資訊放到同一個臨時表中
.
*/
--檢索遊標   下一行如果@@fetch_status為0則繼續迴圈
fetch next from stu_cursor
into @name
end

--關閉遊標
close stu_cursor
--釋放遊標
deallocate stu_cursor

--查詢臨時表#t中的資訊
select name 姓名,sorce 平均分 from #t
--刪除臨時表
drop table #t

23.事務
begin transaction --開啟事務
commit transaction --提交事務
rollback transaction --回滾事務
save transaction--儲存事務,可以儲存部分事務,回滾的時候只有save transaction 以後的事務進行回滾

例子:
begin transaction
declare @nation varchar(20)
set @nation='滿族'
insert into 學生資訊 values('2009010201','李明','男','1984-08-08',@nation,'20090102','北京市')
--save transacton
--其他操作語句
if @nation='漢族'
begin
 commit transaction
end
else
rollback transcation

24.鎖
鎖:封鎖,就是一個事務可以向系統提出請求,對被操作的資料枷鎖Lock。其他事務必須等到此事務解鎖Unlock之後才能訪問該資料。從而,在多個使用者併發訪問資料庫時,確保不互相干擾
。可鎖定的單位是:行,頁,表,盤區和資料庫。

分類:
共享鎖S:讀操作。
    多個事務可封鎖一個共享單位的資料。
    任何事務都不能修改加S鎖的資料。
    通常是加S鎖的資料被讀取完畢,S鎖立即被釋放。
獨佔鎖X:用於寫操作
    僅允許一個事務封鎖此共享資料。
    其他任何事務必須等到X鎖被釋放才能對資料進行訪問。
    X鎖一直到事務結束才能被釋放。
更新鎖U:用來預定要對此頁施加X鎖,它允許其他事務讀,但不允許再施加U鎖或X鎖。
    當被讀取資料頁將要被更新時,則升級為X鎖。
    U鎖一直到事務結束時才能被釋放。

25.系統與元資料函式
convert()  --將一種資料型別的資料轉換為另一種資料型別的資料
current_user  --返回當前使用者的名稱
isdate()  --判斷它的輸入是不是一個有效日期
isnull() --用一個指定替換值替換任何空值
isnumeric()  --判斷它的輸入是不是一個數值

declare @str varchar(10),@i int,@j int
set @str='12'
set @i=10

if isnumeric(@str)=0 --=0不是數值 1是數值
begin
    print convert(int,@str)*@i
end
print isnull(@j,10)*@i --如果為空則賦預設值10
 

26.begin ... end

begin 
{
sql語句
}
end


declare @sex varchar(5)
if @sex is not null
begin
select * from 學生資訊 where 性別[email protected]
print '查詢成功'
end
else
begin
print '查詢資訊失敗,引數為空'
end

27.事務模式
自動提交事務:每條單獨的語句都是一個事務
顯式事務:每個事務均以begin transaction 語句顯式開始,以commit或rollback 語句顯式結束
隱式事務:在前一個事務完成時新事物飲食啟動,但每個事務仍以commit或rollback語句顯式完成
批處理級事務:只能應用於多個活動結果集MARS,在MARS會話中啟動的transact-SQL顯式或飲食事務變為批處理級事務。當批處理完成時沒有提交或回滾的批處理級事務自動又SQL Server進行
回滾
28.XACT_ABORT選項
用於指定當SQL語句出現執行時錯誤時,SQL Server是否自動回滾到當前事務。其語法格式:
set xact_abort{on|off}
當set xact_abort 為on 時,如果執行SQL語句產生執行時錯誤,則整個事務將終止並回滾。當set xact_abort為off時,
有時只回滾產生錯誤的SQL語句,而事務將繼續進行處理。如果錯誤很嚴重,那麼即使set xact_abort為off也可能回滾整個事務。
set xact_abort的設定是在執行或執行時設定,而不是在分析時設定。對於大多數OLE DB提供程式,必須將隱式或顯示事務中的資料修改語句中的xact_abort設定為on 。唯一不需要該選項設
置的情況是在提供程式支援巢狀事務時。

28.死鎖
兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種相互等待的現象,若無外力作用,他們將無法推進下去,此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的
程序成為死鎖程序。
由於佔用資源是互斥的,當某個程序提出申請資源後,使得有關程序在無外力協助下,永遠分配不到必需的資源而無法繼續執行,這就產生了一種特殊現象死鎖。
一種情形,此時執行程式中兩個或多個執行緒發生永久堵塞(等待),每個執行緒都在等待被其他執行緒佔用並堵塞了的資源。例如,如果執行緒A說住了記錄1並等待記錄2,而執行緒B鎖住了記錄2並等
待記錄1,這樣兩個執行緒就發生了死鎖現象。

必要條件:
互斥條件:一個資源每次只能被一個程序使用
請求與保持條件:一個程序因請求資源而阻塞時,對已獲得的資源保持不放。
不剝奪條件:程序已獲得的資源,在未使用完之前,不能強行剝奪。
迴圈等待條件:若干程序之間形成一種頭尾相接的迴圈等待資源關係。
以上四個條件是鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發生鎖。

死鎖的解除和預防
按同一順序訪問物件
避免事務中的使用者互動
保持事務簡短並在一個批處理中
使用低隔離級別
使用繫結連線


死鎖的建議:
對頻繁使用的表使用集蔟化的索引
設法避免一次性影響大量記錄的T-SQL語句,特別是insert和update語句
設法讓update和delete語句使用索引
使用巢狀事務時,避擴音交和回退衝突
對一些資料不需要及時更新值得表在寫SQL的時候在表後臺加nolock如:select * from tableA(nolock)

29.巢狀事務

begin transaction T1
update 班級資訊 set 班級名='金融管理系1班' where 班級編號='20050301'
if exists(select * from 班級資訊 where 班級名='金融管理系1班')
begin
    begin transaction t2
    update 班級資訊 set 輔導員='李銘' where 班級名='金融管理系1班'
    if exists(select * from 輔導員資訊 where 姓名='李銘')
    commit transacton t2
    else
    begin
    rollback transaction t2
    end
    commit transaction t1
end
else
rollback transaction t1


-------------------------------------------------------------------------------------------

1.儲存過程
create proc p_employee
@departmentId varchar(10),
@zhiwei varchar(20)='職員'
as 
select A.員工姓名,A.性別,A.所在職位,A.聯絡電話,B.部門名稱
from 員工資訊 A,部門資訊 B
where a.所在部門編號=B.部門編號 and B.部門編號[email protected] and A.所任職位[email protected]

exec p_employee @departmentid='10001',@zhiwei='經理'

3.create  proc p_sorce
@name varchar(10),
@sorce int output
as
select b.姓名,@sorce=avg(a.分數)
from 成績資訊 a,學生資訊 b
where a.學生編號=b.學號 and b.學號[email protected]

---執行儲存過程
declare @sorce1 int
exec p_sorce @name='張苗苗',@[email protected] output
-- 或者exec p_sorce '張苗苗',@sorce1 output
print @sorce1

4.
create proc sorceforupdate
@id varchar(10),
@sorce int
as
update 成績資訊 set 分數[email protected] where 成績編號[email protected]

--呼叫
exec sorceforupdate @id='3',@sorce=100
5.刪除儲存過程
drop procedure 儲存過程名稱
-- drop proc proc_student
6.設計儲存過程的規則
    可以在儲存過程中引用臨時表
    可以訪問被呼叫
    遠端儲存過程不能回滾更改,不參與事務處理
不能包括的T-SQL語句
create  aggregate 
create rule
create default
create schema  架構
create 或者alter function 函式
create 或alter trigger 觸發器
create 或alter procedure 子儲存過程
create 或alter view 檢視
set parseonly
set showplan_all
set showplan_text
set showplan_xml
use Database_name 切換資料庫

7.系統儲存過程
exec sp_who sa  --登入使用者
exec sp_helpdb 學生成績管理系統    --資料庫的資訊
exec sp_monitor  --資料庫的統計資訊
8.臨時儲存過程 
#區域性臨時儲存過程  ##全域性臨時儲存過程

create procedure #get_info
as
select a.分數,b.姓名  from 成績 a,學生資訊 b where a.學生編號=b.學號 
order by b.學號

--呼叫臨時儲存過程
exec #get_info

drop proc #get_info
 

create procedure ##get_info
as
select a.分數,b.姓名  from 成績 a,學生資訊 b where a.學生編號=b.學號 
order by b.學號

--呼叫臨時儲存過程
exec ##get_info

9.巢狀儲存過程

create proc get_classinfo
as
select * from 班級資訊
exec get_student ‘男’
print @@NESTLEVEL --列印儲存過程級別(巢狀級別)

--呼叫
exec get_classinfo

10.檢視儲存過程
exec sp_helptext get_student


1.儲存過程包含:程式流、邏輯及對資料庫的查詢,接受引數、輸出引數、返回單個或多個結果集及返回值
使用者自定義儲存過程
系統儲存過程
擴充套件儲存過程
create proc 名稱
@引數名稱 引數型別,@引數名稱 引數型別=預設值,@引數名稱 引數型別 output
with {recompile|encryption|recompile,encryption}
as
sql語句

-- with recompile當前引擎不快取儲存過程的執行計劃

create procedure proc_student
@sex varchar(10)
as
select *  from 學生資訊 where 性別[email protected]

exec proc_student @sex='男'

---------------------------------------------------------------------------------------------
1.建立觸發器,當學生資訊表插入資料時,班級表的班級人數+1
create trigger T_addnum
on 學生資訊 
for insert
as 
update 班級資訊 set 班級人數=班級人數+1
where 班級編號=(select 所屬班級 from inserted)

2.
create trigger T_DELETETEACHER
on 教師資訊
for delete
as
select 姓名 as 被刪除的教師,性別,年齡,聯絡電話 from deleted

3.
create trigger t_update
on 教師資訊
for update
as
if (update(姓名) or update(性別))
begin
    print '事務不能被處理,基礎資料不能被修改'
    rollback transaction
end
else
    print '資料修改成功'

4.DDL觸發器 資料定義觸發器
create trigger 觸發器名
on {all server|database}
with encryption
{for|after|event_type}
as
SQL語句


 create trigger T_ontdelete
on detabase
for Drop_table,alter_table
as
print '事務不能被修改,基礎資料表不能被修改和刪除'
rollback

5. 管理觸發器
alter table 員工資訊
disable trigger t_add
alter table 員工資訊
enable trigger t_add
alter table 員工資訊
drop trigger t_add

6.巢狀觸發器
create trigger t_del
on 新員工資訊
for delete
as
insert into 員工資訊表 (員工編號,員工姓名,所在部門編號,所任職位,性別) 
select 員工編號,員工姓名,所在部門編號,所任職位,性別
from deleted

create trigger t_add
on 員工資訊
for insert
as 
update 部門資訊 set 員工人數=員工人數+1
where 部門編號=(select 所在部門編號 from inserted)


delete from 新員工資訊 where 員工編號=14 
select 員工人數 from 部門資訊 where 部門編號='10001'

觸發器最多巢狀32層

7.遞迴觸發器  最多出發16層