I have an old blog that shows one way: http://weblogs.sqlteam.com/tarad/archive/2003/10/15/305.aspxHere's another example but with DELETE TOP:CREATE PROC dbo.isp_Table1_Purge(@purgeDate datetime, @batch int, @purgeSuccess int OUTPUT, @totalRowsPurged int OUTPUT)ASSET NOCOUNT ONDECLARE @error int, @rc intSELECT @purgeSuccess = 1, @totalRowsPurged = 0, @rc = 1 WHILE @rc <> 0BEGIN BEGIN TRAN DELETE TOP (@batch) FROM Table1 WHERE CreateDate < @purgeDate SELECT @rc = @@ROWCOUNT, @totalRowsPurged = @totalRowsPurged + @rc, @error = @@ERROR IF @error <> 0 GOTO EXIT_PROC COMMIT TRANENDRETURNEXIT_PROC:ROLLBACK TRANSET @purgeSuccess = 0 RETURN
These were all written for 2000 and 2005. With the newer versions, I use DELETE TOP but also with TRY/CATCH logic. In the CATCH, I'm looking for error 1205 and retrying if it encounters that. 1205 is the deadlock error code. We retry up to 10 times before giving up.ALTER PROCEDURE [dbo].Blah ASBEGIN SET NOCOUNT ON; DECLARE @err INT, @retries INT, @rowcnt INT, @cnt INT, @total_rows INT, @note VARCHAR(50), @errorMessage NVARCHAR(4000), @errorSeverity INT, @errorState INT; SELECT @total_rows = 0, @rowcnt = 0, @retries = 0 WHILE (1 = 1) BEGIN BEGIN TRY BEGIN TRAN; DELETE ... COMMIT TRAN; BREAK; END TRY BEGIN CATCH IF (@@TRANCOUNT > 0) ROLLBACK TRAN; -- 1205 is deadlock error IF (ERROR_NUMBER() = 1205 AND @retries < 10) BEGIN SET @retries = @retries + 1; WAITFOR DELAY '00:00:10'; END -- some other error or done retrying ELSE BEGIN SELECT @errorMessage = ERROR_MESSAGE(), @errorSeverity = ERROR_SEVERITY(), @errorState = ERROR_STATE(); INSERT INTO ...; RAISERROR (@errorMessage, @errorSeverity, @errorState); RETURN; END END CATCH END
Tara KizerSQL Server MVP since 2007http://weblogs.sqlteam.com/tarad/