长时间运行批量插入锁定表

时间:2018-04-19 15:44:34

标签: sql-server tsql stored-procedures bulkinsert

我有一个存储过程,可以进行几次批量导入的大量数据,每行数量超过200万行。该过程大约需要45分钟,在此期间任何关联的表都将被锁定以防止访问。与后续访问表相关联的等待是LCK_M_SCH_S。

有没有办法阻止这种等待?访问这些表的所有其他过程都是只读的,并且数据不必完美,因此脏读将没有问题。或者检查锁是否存在并返回替代结果。

片段:

BEGIN TRANSACTION;
BEGIN TRY

    truncate table dbo.myTable

    DECLARE @file varchar(500) = 'the dir'

    DECLARE @sql varchar(1000)
    SET @sql = '
            BULK INSERT dbo.myView
            FROM ''' + @file + 'file.txt''
            WITH 
            ( 
                FIELDTERMINATOR =''|'',
                ROWTERMINATOR = ''\n'',
                FIRSTROW = 2,
                CODEPAGE = ''ACP''
            )'
    EXEC(@sql)


END TRY
    BEGIN CATCH

        --error stuff

    END CATCH

    IF @@TRANCOUNT > 0
        COMMIT TRANSACTION

END

如果我无法解决这个问题,那么我是否会批量导入临时表并从那里更新来修复此问题?

1 个答案:

答案 0 :(得分:0)

一种选择可能是拥有2份数据并使用VIEW。视图指向表的一个副本,并且您在另一个副本上执行批量操作。批量操作完成后,您将更新视图的定义以查看已完成批量操作的表。

然后更新原始表,或者在下次批量操作发生时更新原始表,并且每次都在视图中交换对象。这不是一个理想的解决方案,但是,你不能像你想要的那样真正避免表锁;我从不建议使用NOLOCK查询提示。

如果这个答案获得一些赞成票,我不会感到惊讶,因为它不是很好,但确实有用。

另外,我会将FROM ''' + @file + 'file.txt''更改为FROM ' + QUOTENAME(@file + 'file.txt','''')。我不知道@file的价值来自哪里,但是,SQL注入不是你的朋友。