近期第一次用SQL SERVER寫觸發器,發現SQL與ORACLE的觸發器還是有區別的,最大區別:
(1)SQL只有語句級觸發,沒有行級觸發;
(2)ORACLE有語句級觸發和行級觸發;
由於SQL沒有行級觸發,因此單獨使用語句級來編寫觸發器會出現問題。為通俗易懂,舉個例子:用SQL編寫一個update觸發器,在update數據時觸發,若用以下語句
SET @OldMes = ( SELECT rhtype FROM deleted ) SET @UpdateMes = ( SELECT rhtype FROM INSERTED)
在單獨一條一條數據進行更新時不會報錯,但在批量更新時就會報錯,因為SQL執行數據庫觸發器是按語句級來執行,上述SQL語句就相當於把一張表賦值給一個變量,若是單條數據更新,則表里只有一條數據,是不會報錯的,但在多條時就會報錯。
因此,如何在只有語句級觸發的SQL中實現行級觸發?我使用的方法是整張表觸發,即在update時無論是多條數據更新,還是單條數據更新,都將更新的數據放在一張表里,然后將表里的數據依次放在一個變量里,如:
IF UPDATE(address) SELECT @Mesg = '' + @Mesg + '居住地址:' + LTRIM(ISNULL(b.ADDRESS, '')) + ',更新后:' + LTRIM(ISNULL(a.address, '')) + ';' FROM INSERTED a INNER JOIN DELETED b ON a.healthno = b.healthno WHERE ISNULL(a.address, '') <> ISNULL(b.address, '')--@Mesg是聲明的變量
但是,要注意:
(1)上述SQL中ISNULL一定要有,因為SQL查詢中若遇到null,則select出來的是空的,什么都沒有,加上ISNULL(a.address, '')意思就是若a.address是null,則取后面的'',否則則取a.address的值:;
(2) IF UPDATE(address)這條語句一定要有,不然的話若加了insert觸發,則在數據插入時也會執行這條觸發語句。