觸發器:
觸發器為特殊類型的存儲過程,可在執行語言事件時自動生效。SQL Server 包括三種常規類型的觸發器:DML 觸發器、DDL 觸發器和登錄觸發器。
當服務器或數據庫中發生數據定義語言 (DDL) 事件時將調用 DDL 觸發器。登錄觸發器將為響應 LOGON 事件而激發存儲過程。與 SQL Server 實例建立用戶會話時將引發此事件。
當數據庫中發生數據操作語言 (DML) 事件時將調用 DML 觸發器。DML 事件包括在指定表或視圖中修改數據的 INSERT 語句、UPDATE 語句或 DELETE 語句。DML 觸發器可以查詢其他表,還可以包含復雜的 Transact-SQL 語句。將觸發器和觸發它的語句作為可在觸發器內回滾的單個事務對待。如果檢測到錯誤(例如,磁盤空間不足),則整個事務即自動回滾。
主要講述DML觸發器,DML觸發器有兩種:AFTER(FOR),INSTEAD OF觸發器,同時DML 觸發器使用 deleted 和 inserted 邏輯(概念)表。 它們在結構上類似於定義了觸發器的表,即對其嘗試執行了用戶操作的表。 在 deleted 和 inserted 表保存了可能會被用戶更改的行的舊值或新值。
- 對於INSERT 操作,inserted保留新增的記錄,deleted無記錄
- 對於DELETE 操作,inserted無記錄,deleted保留被刪除的記錄
- 對於UPDATE操作,inserted保留修改后的記錄,deleted保留修改前的記錄
示例一:DELETE觸發器的創建和執行,用的Instead Of

示例二:執行刪除一條數據,用deleted來表示被刪除的那條數據,從中獲取

示例三:insert添加一條數據,inserted表示新添加的數據,從中獲取教師編號,並且根據教師編號來查看是男是女,調換男女。

數據庫事務:
數據庫事務(Database Transaction) 是指作為單個邏輯工作單元執行的一系列操作。
事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。
設想網上購物的一次交易,其付款過程至少包括以下幾步數據庫操作:
更新客戶所購商品的庫存信息
保存客戶付款信息--可能包括與銀行系統的交互
生成訂單並且保存到數據庫中 · 更新用戶相關信息,例如購物數量等等 正常的情況下,這些操作將順利進行,最終交易成功,與交易相關的所有數據庫信息也成功地更新。但是,如果在這一系列過程中任何一個環節出了差錯,例如在更新商品庫存信息時發生異常、該顧客銀行帳戶存款不足等,都將導致交易失敗。一旦交易失敗,數據庫中所有信息都必須保持交易前的狀態不變,比如最后一步更新用戶信息時失敗而導致交易失敗,那么必須保證這筆失敗的交易不影響數據庫的狀態--庫存信息沒有被更新、用戶也沒有付款,訂單也沒有生成。否則,數據庫的信息將會一片混亂而不可預測。
數據庫事務正是用來保證這種情況下交易的平穩性和可預測性的技術。
begin tran (或transaction) --開始事務
commit --提交事務
rollback --回滾事務
事務特性:
A原子性(atomicity)
C一致性(consistency)
I隔離性(isolation)
D持久性(durability)
@@ERROR 是判斷事務有沒有錯的條件,無錯時值為0,有錯時值不為0。
select * from cangku
begin tran --開始事務
insert into cangku values(10008,'Boxster',70,10,1004)--沒有錯
if @@ERROR >0
begin--每一個執行語句后面寫這句話是為了如果上一句有錯誤,
--下面不管有多少執行語句,都不會執行,直接到tranrollback
goto tranrollback--到最后一個執行語句的tranrollback
end
insert into cangku values(10002,'極光',66.50,10,1002)--主鍵約束
if @@ERROR>0
goto tranrollback
insert into cangku values(10009,'XF',40,10,1003)--沒有錯
if @@ERROR>0
begin
tranrollback: --需要加上冒號
rollback tran --回滾所有事務中執行過的命令(撤銷所有執行語句)
end
else
begin
commit tran --提交事務(只有真正的走到了commit才是真正的更改數據庫的數據)
end
練習:創建三個表並寫一個簡單的存儲過程,要求可以進貨、出貨並打印小票。
在沒有此貨物並且為進貨時,添加上這一行信息;
在沒有此貨物並且為出貨時,打印沒有此貨物!
use lianxi go create table gong ( gcode int primary key, --供應商編號 gname varchar(20), --供應商名稱 gtel varchar(20) --供應商電話 ) go create table cang ( code int primary key , -- 貨品編號 cname varchar(20), --貨品名稱 cshu int, --貨品數量 cprice decimal(18,2), --貨品價格 cg int, --貨品供應商編號 ) go create table men ( mcode int identity(1000001,1), --貨品編號 mname varchar(20), --貨品名稱 mshu int, --貨品數量 mprice decimal(18,2), -- 貨品價格 mzong decimal(18,2) ) go insert into gong values (1001, '天啟電器','13452236789') insert into gong values (1002, 'Davy家具','17552223761') insert into gong values (1003, '夏華電商','17232235521') insert into gong values (1004, '網易電商','16532238817') select *from gong insert into cang values(231001,'聯想 小新Air 13 Pro',20,5499,1001) insert into cang values(231002,'蘋果iPad mini2',20,1950,1004) insert into cang values(231003,'沙發',12,2699,1002) insert into cang values(231004,'康佳智能冰箱',10,2699,1003) insert into cang values(231005,'微軟 Surface 3',24,3999,1004) insert into cang values(231006,'安吉爾凈水器',10,1668,1003) insert into cang values(231007,'康佳電視 LED55UC2',10,4399,1003) insert into cang values(231008,'Littleswan烘干洗衣機',5,2998,1003) insert into cang values(231009,'Dell 靈越 15 5000',20,3999,1001) insert into cang values(231010,'OPPO R9 全網通',14,2499,1004) insert into cang values(231011,'衣櫃',12,566,1002) insert into cang values(231012,'小米MAX',15,1600,1004) insert into cang values(231013,'洛基亞N1',30,1199,1004) insert into cang values(231014,'紅米手機3S',50,699,1001) insert into cang values(231015,'太陽能',7,1999,1003) insert into cang values(231016,'連體書桌櫃',8,1680,1002) insert into cang values(231017,'海信LED55EC760UC',13,4999,1003) insert into cang values(231018,'xbox-one',20,3799,1004) insert into cang values(231019,'華為P9',20,2860,1004) insert into cang values(231020,'客廳成套家具',3,5644,1002) insert into cang values(231021,'索尼相機',9,4599,1004) insert into cang values(231022,'華碩 W519L',17,3500,1001) insert into cang values(231023,'數碼攝像機',10,2798,1003) insert into cang values(231024,'三星UA55KS9800',5,18099,1003) insert into cang values(231025,'三星 900X3L',15,8999,1001) insert into cang values(231026,'小米平板2',37,999,1004) select *from cang delete from cang create proc chuchu @code int, @cname varchar(20), --貨品名稱 @cshu int, --貨品數量 @cprice decimal(18,2), --貨品價格 @cg int as begin declare @count int select @count=COUNT(*)from cang where code=@code declare @shu int select @shu=cshu from cang where code=@code if @count>0 begin if @cshu>0--進貨 update cang set cshu= @shu+@cshu where code=@code if @cshu<0 --出貨 begin if @shu+@cshu>=0 update cang set cshu=@shu+@cshu where code=@code declare @scshu int set @scshu=-@cshu declare @zong decimal(18,2) set @zong=@cprice*@scshu insert into men values(@cname,@cprice,@scshu,@zong) if @shu+@cshu<0 print '貨物量不足,請及時補充' end end else begin if @cshu>0 insert into cang values (@code,@cname,@cprice,@cshu,@cg) if @cshu<0 print '倉庫中無此貨物' end end go exec chuchu @code=231001,@cname='聯想 小新Air 13 Pro',@cprice=5499,@cshu=15,@cg=1001 exec chuchu @code=231005,@cname='微軟 Surface 3',@cprice=3999,@cshu=-10,@cg=1004 exec chuchu @code=231030,@cname='iphone 3s',@cprice=1200,@cshu=10,@cg=1001 exec chuchu @code=231031,@cname='樂視tv',@cprice=1200,@cshu=-10,@cg=1002 select *from cang select *from men
