2010-12-14 34 views
2

我有一个sql server登录触发器来审计登录名。如何在sql server登录触发器中抑制任何错误条件

我想抑制从它返回的任何错误,因为错误阻止登录。

我该怎么做?

这里是我的触发代码

CREATE TRIGGER [trigLogon_Audit] 
ON ALL SERVER 
FOR LOGON 
AS 
    BEGIN 
     IF (IS_MEMBER('dbo') = 1) RETURN; 
     INSERT INTO Tracking.dbo.Activity (moment, name) VALUES (GETDATE(), ORIGINAL_LOGIN()); 

    END; 
GO 

ENABLE TRIGGER [trigLogon_Audit] ON ALL SERVER 
GO 

回答

1

你可以有错误的触发处理代码,但因为 当触发发生错误批处理已中止,你不能做很多(除非你提出 错误自己使用RAISERROR)。通过厄兰Sommarskog上的错误处理

两个很好的文章:

http://www.sommarskog.se/error-handling-I.html

http://www.sommarskog.se/error-handling-II.html

+0

这些文章是关于SQL Server 2000的。有什么解决方案的SQL Server 2008?我不能相信在现代编程语言中这样简单的事情是不可能的。 – meir 2012-10-02 11:00:31

1

可以静默使用的try/catch

CREATE TRIGGER [trigLogon_Audit] 
ON ALL SERVER 
FOR LOGON 
AS 
SET NOCOUNT ON 
BEGIN TRY 
    IF (IS_MEMBER('dbo') = 1) RETURN; 
    INSERT INTO Tracking.dbo.Activity (moment, name) VALUES (GETDATE(), ORIGINAL_LOGIN()); 
END TRY 
BEGIN CATCH 
    --Do nothing 
END CATCH 
GO 
+0

唯一的问题是,如果它从批次堕胎错误到达catch块,那么你就搞砸了。因此,您将无法在交易中提交或执行更多更新。 – 2010-12-14 15:16:16

+0

@zedo:它是一个登录触发器什么事务? – gbn 2010-12-14 18:25:12

+0

这并没有帮助我。在正常编程语言中,catch块中的异常不会被抑制。 – meir 2012-10-02 10:56:02

0

@ GBN的答案WASN”吞下错误很足够;即使发现异常,登录仍然会失败。奇怪的是,我通过@gbn发现了另一个解决方案,它解决了这个问题:https://dba.stackexchange.com/a/8696/114706。所以这是我确保登录触发器中的异常不会导致所有登录失败的方法。这可能是矫枉过正,但由于这里的例外可能会非常痛苦,所以我宁愿远远不够。

CREATE TRIGGER trigLogon_Audit 
ON ALL SERVER 
FOR LOGON 
AS 
BEGIN 
    BEGIN TRY 
     --make sure that XACT_ABORT is off, or exceptions (even if caught), will cause all logins to fail. 
     DECLARE @XACT_ABORT_WasOn BIT = 0 
     IF (@@OPTIONS & 16384) = 16384 
     BEGIN 
      SET @XACT_ABORT_WasOn = 1 
      SET XACT_ABORT OFF; --this prevents any failure from killing the login. 
     END 

     --Put whatever logic you were trying to execute here; if there's a RETURN statement, make sure that XACT_ABORT gets set back to its original state. 
    END TRY 
    BEGIN CATCH 
     --Do nothing 
    END CATCH 

    --set XACT_ABORT back to its original state. 
    IF (@XACT_ABORT_WasOn = 1) 
    BEGIN 
     SET XACT_ABORT ON; 
    END 
END 
+0

有没有办法在登录触发器中捕获失败的登录错误? – 2017-01-15 22:34:32

+0

那么,大概你可以在@@ error或error_message()的catch块中做一些事情,但是你需要非常小心。例如,将这些值放入表中可能会以多种方式失败,然后您将有错误报告错误。在我看来,即使有登录触发器也是一个相当大的风险,但是如果你无法避免它,你应该进行任何后来对失败有弹性的处理。对于我正在做的事情,我的登录触发器将数据复制到内存优化表中,但依赖数据的过程知道如何在数据丢失时处理它。 – rrreee 2017-01-24 20:47:08