在批次中运行大比较

时间:2017-05-02 18:29:29

标签: sql tsql sql-server-2014

我需要将大表与数百万行进行比较,并将差异插入到日志表中。

问题是存储过程增长(LDF),数据库磁盘空间有限。

我知道提交会将LDF写入MDF。

如何批量执行以下比较,并提交每十万行?

BEGIN TRY
BEGIN TRANSACTION;


            INSERT  INTO dbo.CustomerLog
                    ( OnlineStore ,
                      PhoneNumber ,
                      ChangeType
                    )
                    SELECT  'Online Store a' ,
                            AreaCode + PhoneNumber ,
                            'Added'
                    FROM    dbo.StoreAList a
                    WHERE   NOT EXISTS ( SELECT 1
                                         FROM   dbo.StoreAListCompare b
                                         WHERE  ( b.AreaCode + b.PhoneNumber ) = ( a.AreaCode
                                                              + a.PhoneNumber ) );

COMMIT TRANSACTION                          
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION    
END CATCH;




CREATE TABLE [dbo].[StoreAList](
    [ListID] [bigint] IDENTITY(1,1) NOT NULL,
    [AreaCode] [char](3) NOT NULL,
    [PhoneNumber] [char](7) NOT NULL,
    [RecordDate] [datetime] NULL CONSTRAINT [DF_StoreAList_RecordDate]  DEFAULT (getdate())
) ON [PRIMARY]


CREATE TABLE [dnc].[StoreAListCompare](
    [ListID] [BIGINT] IDENTITY(1,1) NOT NULL,
    [AreaCode] [CHAR](3) NOT NULL,
    [PhoneNumber] [CHAR](7) NOT NULL,
    [RecordDate] [DATETIME] NULL DEFAULT (GETDATE())
) ON [PRIMARY]

1 个答案:

答案 0 :(得分:1)

您可以使用@@rowcount系统变量并批量插入,直到@@rowcount达到0。

请注意dbo.CustomerLog中添加的AND NOT EXISTS ...

例如:

DECLARE @BATCHSIZE INT=100000

WHILE @BATCHSIZE>0
BEGIN
    BEGIN TRY
    BEGIN TRANSACTION;


                INSERT  INTO dbo.CustomerLog
                        ( OnlineStore ,
                          PhoneNumber ,
                          ChangeType
                        )
                        SELECT  TOP(@BATCHSIZE) 
                                'Online Store a' ,
                                AreaCode + PhoneNumber ,
                                'Added'
                        FROM    dbo.StoreAList a
                        WHERE   NOT EXISTS ( SELECT 1
                                             FROM   dbo.StoreAListCompare b
                                             WHERE  ( b.AreaCode + b.PhoneNumber ) = ( a.AreaCode + a.PhoneNumber ) )
                        AND NOT EXISTS (SELECT 1 
                                        FROM dbo.CustomerLog CL
                                        WHERE 'Online Store a'=CL.OnlineStore
                                        AND AreaCode + PhoneNumber=CL.PhoneNumber
                                        AND 'Added'=CL.ChangeType);

                        SET @BATCHSIZE=@@ROWCOUNT

    COMMIT TRANSACTION                          
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION
        SET @BATCHSIZE=0  
    END CATCH;
END