0

ループに 100 レコードを挿入するのに助けが必要です。停止したところから続行し、レコードが完了したら中断します。

Alter PROCEDURE ETL.ETLPurge @PurgeYear INT
AS
BEGIN

  DECLARE @BatchId INT = (SELECT BatchId FROM Tracker)
  declare @Count int
  declare @batchsize int  
  set @batchsize =  100  

  --set @Count = @@rowcount 

 SELECT DISTINCT IDENTITY(INT,1,1) AS ID, MC.ID
  INTO #tmp
  FROM Contact MC
  JOIN Extract CE
    ON MC.ExtractID = CE.ExtractID
  LEFT JOIN Application A 
    ON MC.ID = A.ID
WHERE CE.Year < @PurgeYear   
 AND A.ApplicationId IS NULL  

--declare @counter bigint
--set @counter = 1
--while @counter < 500 
--Begin

--while 1 = 1 
--begin 
Create  NONCLUSTERED INDEX nix_ID
on #tmp(ID) 

--while 1=1
--begin 
INSERT  
--Top (@batchsize) 
INTO Table1 (Values ………)

(
SELECT top (@batchsize)  
@BatchID,  
Values ……..) 
  FROM Contact MC
 inner join 
       #tmp TK on MC.ContactID = TK.ContactID

    --where TK.ID between @batchsize and @ctr + 1
     )
 if @@ROWCOUNT < @batchsize 
 break 
 end 
 --  --continue  
 --  --if @@ROWCOUNT = 0
 -- Break 
end 
 --end 
--number of rows inserted should equal number of rows deleted.
4

1 に答える 1

0

Ok。

これが私のサンプルです。

私に起こったのは、私のデータベース管理者の「チーム」がレプリケーションの設定を台無しにしてしまったことです。それで.. 週末にかけて、犬のように働きました.... ソースデータベースから宛先データベースにレコードを「プルオーバー」するためのコードを書かなければなりませんでした。データベースの構造は同じでした。一部の複製を偽装する必要がありました。

8,000,000 行あり、一度に 10,000 以上を取得しました。以下では、約 1000 行あり、「一度に取得する行数」を 333 に設定しています。うっかり無限ループを作りたくありませんでした。

以下のサンプルは、「while が存在する (宛先データベース テーブルにないソース データベース テーブルの一部のレコード)」という「while」ロジックに基づいています...それらのレコードを取得し続けます。

私はあなたがあなたの質問に答える手助けをしようとしています. 私たちの場合、最終的にレプリケーションが正しく機能するようになり、これらのスクリプトを破棄することができました。楽しい週末ではありませんでした。

/* 設定 */

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeCategorySourceTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    BEGIN
        DROP TABLE [dbo].[CodeCategorySourceTable]
    END
GO

CREATE TABLE [dbo].[CodeCategorySourceTable] (
    CodeCategoryUUID [uniqueidentifier] not null default NEWSEQUENTIALID() , 
    CodeCategoryName varchar(64) not null
)
GO

ALTER TABLE [dbo].[CodeCategorySourceTable] ADD CONSTRAINT PK_CodeCategorySourceTable_CodeCategoryUUID
PRIMARY KEY CLUSTERED (CodeCategoryUUID)
GO

ALTER TABLE [dbo].[CodeCategorySourceTable] ADD CONSTRAINT CK_CodeCategorySourceTable_CodeCategoryName_UNIQUE 
UNIQUE (CodeCategoryName)
GO



if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[CodeCategoryDestinationTable]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    BEGIN
        DROP TABLE [dbo].[CodeCategoryDestinationTable]
    END
GO

CREATE TABLE [dbo].[CodeCategoryDestinationTable] (
    CodeCategoryUUID [uniqueidentifier] not null default NEWSEQUENTIALID() , 
    CodeCategoryName varchar(64) not null
)
GO

ALTER TABLE [dbo].[CodeCategoryDestinationTable] ADD CONSTRAINT PK_CodeCategoryDestinationTable_CodeCategoryUUID
PRIMARY KEY CLUSTERED (CodeCategoryUUID)
GO

ALTER TABLE [dbo].[CodeCategoryDestinationTable] ADD CONSTRAINT CK_CodeCategoryDestinationTable_CodeCategoryName_UNIQUE 
UNIQUE (CodeCategoryName)
GO




declare @AlreadyExistingCodeCategoryUUID01 uniqueidentifier
declare @AlreadyExistingCodeCategoryUUID03 uniqueidentifier
declare @AlreadyExistingCodeCategoryUUID02 uniqueidentifier
declare @AlreadyExistingOldCodeCategoryName01 varchar(64)
declare @AlreadyExistingOldCodeCategoryName02 varchar(64)
declare @AlreadyExistingOldCodeCategoryName03 varchar(64)
declare @AlreadyExistingNewCodeCategoryName01 varchar(64)
declare @AlreadyExistingNewCodeCategoryName02 varchar(64)
declare @AlreadyExistingNewCodeCategoryName03 varchar(64)



select @AlreadyExistingCodeCategoryUUID01 = NEWID(), @AlreadyExistingCodeCategoryUUID02 = NEWID(), @AlreadyExistingCodeCategoryUUID03 = NEWID()
select @AlreadyExistingNewCodeCategoryName01 = 'NewOne', @AlreadyExistingNewCodeCategoryName02 = 'NewTwo', @AlreadyExistingNewCodeCategoryName03 = 'NewThree'
select @AlreadyExistingOldCodeCategoryName01 = 'OldOne', @AlreadyExistingOldCodeCategoryName02 = 'OldTwo', @AlreadyExistingOldCodeCategoryName03 = 'OldThree'


Insert Into [dbo].[CodeCategorySourceTable] ( CodeCategoryUUID , CodeCategoryName )
Select top 1000 NEWID() , convert(varchar(40), NEWID()) + 'Name' from dbo.sysobjects so1 cross join dbo.sysobjects so2


Insert Into [dbo].[CodeCategorySourceTable] ( CodeCategoryUUID , CodeCategoryName )
select @AlreadyExistingCodeCategoryUUID01, @AlreadyExistingNewCodeCategoryName01 
UNION ALL select @AlreadyExistingCodeCategoryUUID02, @AlreadyExistingNewCodeCategoryName02
UNION ALL select @AlreadyExistingCodeCategoryUUID03, @AlreadyExistingNewCodeCategoryName03


select count(*) from [dbo].[CodeCategorySourceTable] as CodeCategorySourceTableCOUNT



Insert Into  [dbo].[CodeCategoryDestinationTable] ( CodeCategoryUUID , CodeCategoryName )
select @AlreadyExistingCodeCategoryUUID01, @AlreadyExistingOldCodeCategoryName01
UNION ALL select @AlreadyExistingCodeCategoryUUID02, @AlreadyExistingOldCodeCategoryName02
UNION ALL select @AlreadyExistingCodeCategoryUUID03, @AlreadyExistingOldCodeCategoryName03

select count(*) from  [dbo].[CodeCategoryDestinationTable] as CodeCategoryDestinationTableCOUNT

/* USP */

print '[uspCodeCategoryReplicateReplacer]'
go


IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[uspCodeCategoryReplicateReplacer]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[uspCodeCategoryReplicateReplacer]
Go


/*


declare @numberRowsAffected  int
declare @ErrorNumber int

exec [dbo].[uspCodeCategoryReplicateReplacer] @numberRowsAffected output , @ErrorNumber  output

print @numberRowsAffected 
print @ErrorNumber 
print ''

*/



CREATE PROCEDURE [dbo].[uspCodeCategoryReplicateReplacer] (
@numberRowsAffected int output
,
@ErrorNumber int output
)

AS


SET NOCOUNT ON

select @ErrorNumber = 0

declare @ErrorTracker int 
declare @insertRowCount int
declare @updateRowCount int 
select @insertRowCount = 0
select @updateRowCount = 0
declare @CurrentInsertCount int



declare @ManualReplicationRowCount int
select @ManualReplicationRowCount = 333


declare @MaximumLoopCounter int 
select @MaximumLoopCounter = 10000



while (@MaximumLoopCounter > 0) and exists 
(
    Select
        TOP 1 null
        from [dbo].[CodeCategorySourceTable] sourceTable with (nolock)
        where not exists
        (
            select null from  [dbo].[CodeCategoryDestinationTable] destinationTable with (nolock) 
            Where
                destinationTable.CodeCategoryUUID = sourceTable.CodeCategoryUUID 
        )
)



    BEGIN


        select @MaximumLoopCounter = @MaximumLoopCounter - 1

        /*  DELETE FROM  [dbo].[CodeCategoryDestinationTable] */

        SET NOCOUNT OFF

        Insert into  [dbo].[CodeCategoryDestinationTable]  
        (   
                CodeCategoryUUID, 
                CodeCategoryName

        )

        Select

            TOP (@ManualReplicationRowCount)

                CodeCategoryUUID, 
                CodeCategoryName

            from [dbo].[CodeCategorySourceTable] sourceTable with (nolock)

            where not exists
            (
                select null from  [dbo].[CodeCategoryDestinationTable]   destinationTable with (nolock) 
                Where
                    destinationTable.CodeCategoryUUID = sourceTable.CodeCategoryUUID 
            )




            SELECT @CurrentInsertCount = @@ROWCOUNT , @ErrorTracker = @@ERROR
            select @insertRowCount = @insertRowCount + @CurrentInsertCount

            if @ErrorTracker <> 0
                BEGIN

                    select @ErrorNumber = @ErrorTracker 
                    select @MaximumLoopCounter = 0 /*Bail Out !!!*/
                END



            SET NOCOUNT ON




    END /*End While Loop*/











print '/Before Look  [dbo].[CodeCategoryDestinationTable] */'
select * from  [dbo].[CodeCategoryDestinationTable]



SET NOCOUNT OFF

/* A little extra.  Update any non-surrogate-key values... We did not do this, but I leave it here as for kicks */

Update  [dbo].[CodeCategoryDestinationTable]
Set
  /*CodeCategoryUUID = vart.CodeCategoryUUID,*/
CodeCategoryName = sourceTable.CodeCategoryName
From
     [dbo].[CodeCategoryDestinationTable] destinationTable, [dbo].[CodeCategorySourceTable] sourceTable
Where
/*Relationship*/
destinationTable.CodeCategoryUUID = sourceTable.CodeCategoryUUID  
/*Filter*/
and destinationTable.CodeCategoryName <> sourceTable.CodeCategoryName


SELECT @updateRowCount = @@ROWCOUNT

SET NOCOUNT ON

print '/After Look  [dbo].[CodeCategoryDestinationTable] */'
select * from  [dbo].[CodeCategoryDestinationTable]




print '/@insertRowCount COUNT/'
print @insertRowCount 
print '-------------------------'

print '/@updateRowCount COUNT/'
print @updateRowCount 
print '-------------------------'

SELECT @numberRowsAffected = @insertRowCount + @updateRowCount


print '/ [dbo].[CodeCategoryDestinationTable] COUNT/'
print @numberRowsAffected 
print '-------------------------'







SET NOCOUNT OFF


GO

/*GRANT EXECUTE ON dbo.uspCodeCategoryReplicateReplacer TO $(DBUSERNAME)*/

GO

/* 改善、ManualReplicationRowCount "getter" をカプセル化して、1 か所で変更できるようにします */

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[uspInternalSettingGetManualReplicationRowCount]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[uspInternalSettingGetManualReplicationRowCount]
GO

/*

--START TEST

declare @returnCode int
declare @ManualReplicationRowCount int

EXEC @returnCode = dbo.uspInternalSettingGetManualReplicationRowCount @ManualReplicationRowCount output
print @ManualReplicationRowCount
print '/@returnCode/'
print @returnCode




*/

CREATE PROCEDURE [dbo].[uspInternalSettingGetManualReplicationRowCount] (
@ManualReplicationRowCount int output  --return
)

AS

SET NOCOUNT ON 

select @ManualReplicationRowCount = 333

SET NOCOUNT OFF
GO
于 2013-02-27T18:51:36.240 に答える