1

当在视图中执行查询出错时,我正在尝试向我的日志添加一个警报,以便将视图运行插入表中。当我单独运行视图时,我在 SUBSTRING 中得到一个无效的输入(我不记得错误的确切措辞)。当我将它作为视图的一部分运行时-> 表存储过程,该错误被忽略,然后我必须去挖掘有问题的行并在视图的代码中创建一个异常以从结果中省略该行(我知道,它听起来很杂乱,但我正在从专门的 web 应用程序中对巨大的 web 日志文件进行数据缩减),但我离题了。

我尝试了两种不同的方法来尝试捕获错误,但都没有以在我的执行结果表 (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
4

3 回答 3

3

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

这里

于 2013-01-22T23:26:26.283 回答
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不会得到它(除非你添加另一个检查)

于 2013-01-22T23:35:04.887 回答
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
于 2013-01-24T18:51:06.317 回答