当我在视图中执行查询时出错时,我正在尝试向我的日志添加警报,以便将视图运行插入到表中。当我单独运行视图时,我得到一个无效的输入到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
答案 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