TSQL错误检查代码不起作用

时间:2013-01-22 23:09:15

标签: sql sql-server tsql error-handling transactions

当我在视图中执行查询时出错时,我正在尝试向我的日志添加警报,以便将视图运行插入到表中。当我单独运行视图时,我得到一个无效的输入到SUBSTRING(我记不起的错误的确切措辞)。当我将其作为我观点的一部分运行时 - >表存储过程,错误被忽略,然后我必须去挖掘违规行,并在视图的代码中做一个异常,从结果中省略该行(我知道,它听起来像kludge-y,但我正在做数据减少来自专门的webapp的巨大网络日志文件),但我离题了。

我尝试了两种不同的方法来尝试捕获错误,并且都没有以这种方式触发,在我的执行结果表(refresh_results)中插入指示错误的行。我想我可能会遗漏一些基本的东西 - 也许这些错误正在被封装。如果我无法检测到错误,则注意错误的唯一方法是,如果有人注意到表中的条目数量在给定的时间段内较低。

    SELECT @TransactionName = 'tname';
    BEGIN TRANSACTION @TransactionName;
    BEGIN TRY
      print 'tname ***In Try***';
      if exists (select name from sysobjects where name='tablename')
      begin
        drop table tablename;
      end
      select * into tablename 
      from opendatasource('SQLNCLI', 'Data Source=DATABASE;UID=####;password=####').dbo.viewname;
      COMMIT TRANSACTION @TransactionName;
    END TRY
    BEGIN CATCH 
      print 'tablename ***ERROR - check for SUBSTRING***';
      begin transaction
      set   @result_table = 'tablename ***ERROR - check for SUBSTRING***'
      select    @result_time = getdate(),
            @result_rows = count(logtime)
      from tablename
      insert INTO   [dbo].[refresh_results] (result_time, result_table, result_rows)
                values (@result_time, @result_table, @result_rows);
      commit transaction
      ROLLBACK TRANSACTION @TransactionName;
    END CATCH 

    if exists (select name from sysobjects where name='tablename')
    begin
      drop table tablename;
    end
    select * into tablename 
    from opendatasource('SQLNCLI', 'Data Source=DATABASE;UID=####;password=####').dbo.viewname;

    print '@@error' 
print @@error

if @@error <> 0 
Begin
      print 'tablename ***ERROR - check for SUBSTRING***';
      set     @result_table = 'tablename ***ERROR - check for SUBSTRING***'
      select  @result_time = getdate(),
          @result_rows = count(logtime)
      from tablename
      insert INTO   [dbo].[refresh_results] (result_time, result_table, result_rows)
                values (@result_time, @result_table, @result_rows);
    End

3 个答案:

答案 0 :(得分:3)

您的嵌套交易没有按您的想法进行。您正在回滚您认为存储的错误。回滚初始事务,然后,如果您觉得有必要,请启动一个新事务来记录错误。

请参阅here

答案 1 :(得分:2)

你有两个独立的问题

在第一个示例中,您正在运行执行以下操作的事务:

BEGIN TRAN
    ...error...
    BEGIN TRAN
        ...log error...
    COMMIT TRAN
ROLLBACK TRAN

使用外部事务回滚内部事务。也许试试:

BEGIN TRAN
    ...error...
ROLLBACK TRAN
BEGIN TRAN
    ...log error...
ROLLBACK TRAN

您正在使用@@ERROR的第二个示例。据我所知,只要你运行@@ERROR就会被替换掉。我认为这包括印刷声明。

如果您将其更改为:

DECLARE @Error INT
select * into tablename 
from opendatasource('SQLNCLI', 'Data Source=DATA3;UID=;password=').dbo.viewname;

SET @Error = @@ERROR
print '@@error' 
print @Error

if @Error <> 0
...log the error

TRY CATCH的优点是,如果您有错误,它会捕获它。 @@ERROR方法可以100%运行,但它仅适用于最后一行。因此,如果您在DROP TABLE tablename @@ERROR时出错,则无法获取(除非您添加其他支票)

答案 2 :(得分:0)

好的,所以我不得不使用帮助程序来添加日志条目。我认为发生的事情是回滚也回滚了日志条目。

这就是我必须做的事情:

    DECLARE @myError tinyint;
    BEGIN TRY
        BEGIN TRANSACTION;      
        if exists (select name from sys.sysobjects where name='table_name')
        begin
          drop table table_name
        end
        select * into table_name
          from opendatasource('SQLNCLI', 'Data Source=###;UID=###;password=###').view_Table
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH 
        set @myError = 1                
        ROLLBACK TRANSACTION;
    END CATCH

    if @myError <> 0
    begin
        exec dbo.table error
    end
    ELSE
        EXEC  exec dbo.table normal row