2012-02-16 243 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