2012-02-16 212 views
2

我使用SQL Server 2008 R2SQL服務器觸發不插入

我有一個簡單的觸發

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN 
SET NOCOUNT ON 

insert into syn_HistoriquePersonne 
    (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
     Champ2, Champ3, Champ4 SiteAssocie) 
select GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
     Champ4, SiteAssocie 
from inserted 
END 

它可以正常工作。問題是,我工作的程序有一個可怕的代碼庫,所以我的老闆不想在表Personne上觸發回滾,即使它失敗了。我知道這真的不太可能,但是他在數據庫活動巨大的情況下害怕超時...... ANYWAY

所以我搜索了觸發器中的提交。並改變了觸發:

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN 
SET NOCOUNT ON 

COMMIT 

insert into syn_HistoriquePersonne 
    (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
     Champ2, Champ3, Champ4 SiteAssocie) 
select GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
     Champ4, SiteAssocie 
from inserted 
END 

但觸發保持拍攝消息

交易在觸發停止,批量中止。

所以我做了這樣的:

CREATE TRIGGER [dbo].[T_Personne_ITrig] ON [dbo].[Personne] FOR INSERT AS 
BEGIN 
SET NOCOUNT ON 

COMMIT 
BEGIN TRAN 
insert into syn_HistoriquePersonne 
    (hpers_Timestamp, Supprime, ID, Nom, Prenom, Champ1, 
     Champ2, Champ3, Champ4, SiteAssocie) 
select GETDATE(), 0, ID, Nom, Prenom, Champ1, Champ2, Champ3, 
     Champ4, SiteAssocie 
from inserted 
END 

它停止這樣做批處理中止,但似乎從來沒有在我的歷史表中插入任何東西......我讀到的主題,這應該工作我認爲。但它不...

其他人已經有這個問題,我該如何解決?

我正在做簡單插入來測試我的觸發器。

+1

只要不在你的觸發器中調用ROLLBACK,那麼你應該沒問題。不要在觸發器中啓動新的事務...觸發器應始終在引起它觸發的操作的上下文中執行。 – 2012-02-16 15:58:23

+0

我不會在我的觸發器中調用回滾,但如果發生超時,應用程序將會返回。我知道tran tran並不是最佳選擇,但它確實會阻止錯誤信息。但真正的問題是爲什麼插入不工作... – 2012-02-16 16:01:14

+0

但你說在你的第一個代碼片段:*它正常工作* - 那又有什麼問題?如果發生超時 - 在觸發器內部無法處理任何事情...... – 2012-02-16 16:02:15

回答

2

不幸的是,你正在吠叫錯誤的樹。你不能以這種方式玩事務。

如果唯一擔心的是插入失敗,則可以簡單地在插入代碼時進行檢查。或者只是在確保桌子上的限制準確反映它的用途方面非常艱難。但是,由於您也擔心導致命令超時的進程持續時間,所以這不會完全覆蓋您(實際上它會使得超時的可能性更小)。

我看到工作的唯一方法是大量簡化插入語句,並將一些內容(所有數據,或只是時間戳和ID?)插入到沒有約束或索引的保留表中。然後您需要重複調​​用服務器端進程來處理您的保存表。

由於您的情況似乎只是維護一個歷史日誌,所以也許一個選項可以像從歷史表中刪除所有約束一樣簡單。所有的解決方案都有點骯髒,但是這時老闆的要求似乎有點不尋常;我認爲答案應該是能力計劃。

我不知道這是否符合您的真實世界的情況,但我希望它可以幫助。

+0

歷史表已經沒有任何限制。但問題是,即使我沒有Begin Tran語句,如果我在插入日誌表之前在觸發器中提交了一個提交,插入似乎也沒有工作......這就像我從來沒有在插入時調用插入所有,我不明白爲什麼。 – 2012-02-16 16:11:24

+0

如果代碼執行插入並且它應該執行它,我會跟蹤一些打印。但是由於一個未知的原因,沒有插入任何東西,我根本沒有收到任何錯誤信息。 – 2012-02-16 16:16:18

+0

@AlexJean - 根據我的回答的第一行:你不能玩這樣的交易。 BEGIN TRANSACTION和COMMIT TRANSACTION ***必須在相同的範圍內。如果應用程序的SQL命令開始事務,那麼應用程序的命令必須提交它。正如你在桌子上使用約束條件等,你不會讓它變得更快,這是你可以做的唯一的事情。 (試圖在你所瞄準的目標下構建命令超時故障保險箱根本無法實現。) – MatBailie 2012-02-16 16:28:35