0

我们有一个数据导入系统,我们正在处理 CSV 文件,每个文件都包含一组必须单独验证和处理的记录。如果它们由于某种原因失败,它们会被标记为错误,然后我们继续下一条记录。它们可能因逻辑错误或数据库错误(例如重复键或外键错误)而失败。

处理数据的存储过程要么从客户端应用程序调用,要么从代理作业调用。不同之处在于应用程序将创建事务,而作业在调用 proc 之前不会。

SET NOCOUNT ON;
SET XACT_ABORT OFF;

DECLARE @trancount_in       INT,
        @xstate             INT,
        @Row                INT,
        @MaxRows            INT

SET @trancount_in = @@trancount

-- CODE: import data into temp table
select @Row = 1,
       @MaxRows = @@Rowcount

IF @transcount_in = 0 
    BEGIN TRANSACTION

while @Row <= @MaxRows

    -- CODE: Get data record from table  

    begin try

        save transaction myproc

        -- CODE: validate and process record

    end try

    begin catch

        SELECT @xstate = XACT_STATE()

        IF @xstate = -1 BEGIN
            ROLLBACK
            Raiserror('error',16,1)
        END
        IF @xstate = 1 and @@Trancount = 0 BEGIN
            ROLLBACK
            Raiserror('error',16,1)
        END
        IF @xstate = 1 and @@Trancount > 0
            ROLLBACK TRANSACTION myproc

        -- CODE: update import record with error here

    end catch

    set @Row = @Row + 1
End

IF @transcount_in = 0 
    COMMIT

到目前为止相当简单,但是查看大量文档,它说您应该在 catch 块中检查 xact_state 是否为 -1,但我不希望此时事务失败。我只想继续导入的下一行。因此,如果 xact_abort 关闭,我们会在 catch 块中获得 -1 的 xact_state 吗?

我知道 catch 实际上并没有捕获所有错误,但是我发现如果您使用 try catch 块创建父 proc,那么它将捕获比实际 proc 中的块更多的错误。所以我会将循环逻辑移动到父进程,然后在当前进程中进行处理。

我还应该做些什么来减轻可能发生的任何错误?

希望这不会太混乱。干杯阿德里安

4

0 回答 0