登录到 SQL Server 触发器中的表

发布于 2024-09-01 01:48:33 字数 424 浏览 2 评论 0原文

我正在编写 SQL Server 2005 触发器。我想在触发器执行期间使用 INSERT 语句到我的日志表中进行一些日志记录。当执行过程中发生错误时,我想引发错误并取消导致触发器执行的操作,但不丢失日志记录。实现这一目标的最佳方法是什么?

现在,我的触发器会记录除出现错误时的情况之外的所有内容 - 因为回滚。需要 RAISERROR 语句来通知调用程序有关错误的信息。

现在,我的错误处理代码如下所示:

if (@err = 1)
begin
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output
    RAISERROR (@msg, 16, 1)
    rollback transaction
    return
end

I am coding SQL Server 2005 trigger. I want to make some logging during trigger execution, using INSERT statement into my log table. When there occurs error during execution, I want to raise error and cancel action that cause trigger execution, but not to lose log records. What is the best way to achieve this?

Now my trigger logs everything except situation when there is error - because of ROLLBACK. RAISERROR statement is needed in order to inform calling program about error.

Now, my error handling code looks like:

if (@err = 1)
begin
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output
    RAISERROR (@msg, 16, 1)
    rollback transaction
    return
end

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

煮茶煮酒煮时光 2024-09-08 01:48:33

另一种可能的选择是使用表变量来捕获要存储在永久日志表中的信息。如果给出 ROLLBACK TRANSACTION 命令,则表变量不会回滚。示例代码如下...



--- Declare table variable
DECLARE @ErrorTable TABLE
  ( [DATE]  smalldatetime,
    [ENTRY] varchar(64) )

DECLARE @nErrorVar  int

--- Open Transaction
BEGIN TRANSACTION

--- Pretend to cause an error and catch the error code
SET @nErrorVar = 1  --- @@ERROR

IF (@nErrorVar = 1)
  BEGIN

    --- Insert error info table variable
    INSERT INTO @ErrorTable 
      ( [Date], [Entry] )
    SELECT
        getdate(), 'Error Message Goes Here'

    RAISERROR('Error Message Goes Here', 16, 1)

    ROLLBACK TRANSACTION

    --- Change this to actually insert into your permanent log table
    SELECT  *
    FROM    @ErrorTable

  END

IF @@TRANCOUNT  0
  PRINT 'Open Transactions Exist'
ELSE
  PRINT 'No Open Transactions'

Another possible option is to use a table variable to capture the info you want to store in your permanent log table. Table variables are not rolled back if a ROLLBACK TRANSACTION command is given. Sample code is below...



--- Declare table variable
DECLARE @ErrorTable TABLE
  ( [DATE]  smalldatetime,
    [ENTRY] varchar(64) )

DECLARE @nErrorVar  int

--- Open Transaction
BEGIN TRANSACTION

--- Pretend to cause an error and catch the error code
SET @nErrorVar = 1  --- @@ERROR

IF (@nErrorVar = 1)
  BEGIN

    --- Insert error info table variable
    INSERT INTO @ErrorTable 
      ( [Date], [Entry] )
    SELECT
        getdate(), 'Error Message Goes Here'

    RAISERROR('Error Message Goes Here', 16, 1)

    ROLLBACK TRANSACTION

    --- Change this to actually insert into your permanent log table
    SELECT  *
    FROM    @ErrorTable

  END

IF @@TRANCOUNT  0
  PRINT 'Open Transactions Exist'
ELSE
  PRINT 'No Open Transactions'
写给空气的情书 2024-09-08 01:48:33

这里的问题是日志记录是修改数据的事务的一部分。嵌套事务在这里没有帮助。您需要的是将记录操作放入单独的上下文(连接)中,即使其独立于当前事务。

我想到了两个选择:

  • 使用 Service Broker 用于日志记录 - 将日志数据放入队列,接收并保存数据“在管道的另一侧”(即在另一个进程/连接/事务中)
  • 使用 OPENQUERY - 您需要将自己的服务器注册为“链接服务器”并“远程”执行查询(我知道,这看起来是有点奇怪,但无论如何都是一个选择......)

HTH

The problem here is that logging is part of transaction that modifies your data. Nested transactions will not help here. What you need is to put you logging actions into a separate context (connection), i.e. make it independent from you current transaction.

Two options come to my mind:

  • use Service Broker for logging - put log data to queue, receive and save the data 'on the other side of the pipe' (i.e. in another process/connection/transaction)
  • use OPENQUERY - you will need to register you own server as a 'linked server' and execute queries 'remotely' (I know, this looks a little bit strange, but an option anyway ...)

HTH

猥琐帝 2024-09-08 01:48:33

不知道我是否想得太简单,但为什么不只是更改错误处理程序的顺序以在回滚之后插入?

if (@err = 1)
begin
    RAISERROR (@msg, 16, 1)
    rollback transaction
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output
    return
end

Don't know if I'm thinking too simple, but why not just change the order of the error handler to insert AFTER the rollback??

if (@err = 1)
begin
    RAISERROR (@msg, 16, 1)
    rollback transaction
    INSERT INTO dbo.log(date, entry) SELECT getdate(), 'ERROR: ' + out from #output
    return
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文