SQL 使用觸發器常見錯誤


   今天做代碼審查時,看見以下一段觸發器的創建腳本,我們一起來分析一下

create trigger [trigger_puClassRoomType]
on [dbo].[puClassRoomType]
AFTER update
as 
declare @roomname nvarchar(100),@roomnumber nvarchar(100)
select @roomname = TypeName,@roomnumber=TypeNumber from Inserted
begin
update ExamingClasses set TypeName=@roomname where TypeNumber=@roomnumber
update PlanNumTimePlace set ClassroomName=@roomname where Classroomnum=@roomnumber
end
go

  書寫這段代碼的程序員可能對 1、SQLServer變量賦值 2、觸發器Inserted表 這兩個概念模糊,首先我們談談Inserted表,代碼段中對Inserted表的查詢方式沒有帶任何條件,似乎這張表只有單行一樣,這明顯是錯誤的。

  SQL Server為每個觸發器創建了兩個專業表:INSERTED表和DELETED表。這兩個邏輯表,由系統來維護。用戶不能對它們進行修改。它們存放在內存中而不是數據庫中。這兩個表的結構總與被該觸發器作用的表的結構相同。觸發器執行完成后,與該觸發器相關的這兩個表也被刪除。

  • INSERTED表:存放由於執行INSERT或UPDATE語句而要向表中插入的所有行。在執行INSERT或UPDATE操作時,新的行同時添加到激活觸發器的表和INSERTED表中,INSERTED表的內容是激活觸發器的表中的新行的備份
  • DELETED表:存放由於執行DELETE或UPDATE語句而要從表中刪除的所有行。在執行DELETE或UPDATE操作時,被刪除的行從激活觸發器的表中被移動到DELETED表,這兩個表不會有共同的行。

  認識到INSERTED表的內容是根據更新條件來的,所以我覺得在使用INSERTED表的時候可以配合游標CURSOR來使用。同時提醒一下,以上代碼段中讀取INSERTED表的方式,將會返回INSERTED表的最后一行來進行賦值

  SQL Server變量賦值的方式用兩種,分別是SET和SELECT,代碼段中選擇了使用SELECT,而SQL Server推薦使用SET對變量進行賦值。雖然我們在日常工作中使用SELECT的場景比較多,兩個賦值方式的概念也了比較解,但他們兩者的區別我還是想再強調一下,當賦值失敗時,SET和SELECT 的行為是不一樣的。這里的賦值失敗可能是沒有數據或者數據類型不匹配等。此時SELECT會返回上一個值(如果上一個值已經賦值成功),而SET會把NULL賦值給變量。

  • 使用SET的情景:1、需要直接賦值,且不需要任何查詢,比如變量初始化。2、故意賦予NULL值。3、為了將來的移植而遵循ANSI標准。4、賦予非標量值。
  • 使用SELECT的情景:1、直接賦予多值變量。2、通過查詢來賦予變量(單值或多值均可)。3、減少代碼量。4、為了獲取變量如@@ROWCOUNT和@@ERROR的值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM