2012-09-07 30 views
1

我的數據庫部分由外部CRM創建和編輯,其中某些表在其觸發器之後有多個(最多2個)。這是由於CRM自動生成了一個觸發器(我有限制的控制權),另一個觸發器包含我的代碼。Sqlserver標準觸發器訂單

CRM觸發器爲插入的數據行生成主鍵。我的觸發器需要訪問該主鍵,以便將其作爲外鍵寫入另一個表。我使用

Select @id=max(id) from mytable 

因爲Scope_Identity沒有以某種方式產生想要的結果。

這工作,直到我讓CRM重新創建表和自己的觸發器。我的觸發器選擇的該表的最大ID似乎始終爲actual_id - 1

當我改變我的觸發器使用相同的代碼它一直有程序再次工作。

我的問題是: SQL服務器(我正在使用SQL Server 2008)是否按創建時間設置其觸發器順序?

和: 是

sp_settriggerorder @triggername='mycustomtrigger', @order='Last', @stmttype='INSERT' 

將永久地改變這個還是我必須再次調用該程序,每次CRM再現其觸發的時間? (使用DROP和CREATE,而不是ALTER)

希望這個答案能幫助有人看到同一個問題。

問候

+2

對於任何多行語句,'select @ id = max(id)from mytable'中斷。爲什麼不在觸發器中使用'inserted'和'deleted'僞表? –

回答

2

這不是記錄,但我相信LAST設置將保持與觸發器,只要它不被修改。 (相反,它記錄,如果它被修改觸發器將失去此設置)。然而,它似乎工作:

create table T (ID int not null) 
go 
create trigger T_T1 on T 
after insert 
as 
    RAISERROR('T1',10,1) WITH NOWAIT 
go 
create trigger T_T2 on T 
after insert 
as 
    RAISERROR('T2',10,1) WITH NOWAIT 
go 
create trigger T_T3 on T 
after insert 
as 
    RAISERROR('T3',10,1) WITH NOWAIT 
go 
insert into T(ID) values (1) 
go 
sp_settriggerorder 'T_T2','Last','INSERT' 
go 
insert into T(ID) values (2) 
go 
drop trigger T_T1 
go 
create trigger T_T1 on T 
after insert 
as 
    RAISERROR('T1',10,1) WITH NOWAIT 
go 
insert into T(ID) values (3) 

結果:

T1 
T2 
T3 

(1 row(s) affected) 
T1 
T3 
T2 

(1 row(s) affected) 
T3 
T1 
T2 

(1 row(s) affected) 

關於你的第一個問題,但是:

是否SQL服務器(我使用SQL Server 2008中)設置其按創建時間觸發訂單?

它還似乎,但我不會依靠這一點。 sp_settriggerorder是任何訂單記錄的唯一地方。

最後,正如我在評論中提到的,我不會依賴你當前的Select @id=max(id) from mytable方法 - 它可能因爲多種原因而被打破,但最重要的是每個方法觸發一次觸發器,並可能觸發爲響應多行行,所以您應該寫觸發器來使用inserted僞表(而不是期望它包含0,1行或多行)。

+0

謝謝。我不能依賴於插入的表的ID,因爲ID正在被第一次觸發後更新。當處理批量插入時,'Scope_Identity()'顯然無助於我(儘管在我們的例子中**不應該發生) – LuigiEdlCarno