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

好的。

这是我的样本。

发生在我身上的是我的 dba “团队” .. 搞砸了为我们设置复制。所以..在周末,像狗一样工作....我们不得不编写一些代码来将记录从源数据库“拉”到目标数据库,其中数据库的结构是相同的。我们不得不伪造一些复制。

我们有 8,000,000 行,我们一次会将它们拉到 10,000 多个。下面,我有大约 1000 行,并将“一次拉取的行数”设置为 333。我还放置了一个 @MaximumLoopCounter 作为“以防万一”。我不想意外地创建一个无限循环。

下面的示例将其“while”逻辑基于“while exists(源数据库表上的一些记录不在目标数据库表中)”......继续抓取这些记录。

我试图帮助你回答你的问题。在我们的例子中,我们最终让复制工作正常,并且我们能够放弃这些脚本。这不是一个有趣的周末。

/* 设置 */

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

/* 美国药典 */

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”,以便在一处更改 */

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 回答