如何在 SQL Server 中从我的修剪存储过程中一次删除 n 行?

jjs*_*jss 0 sql sql-server stored-procedures

我有一个存储过程,可以删除超过特定日期的所有数据。但我想添加该功能,以便它一次只删除 1000 行。

我有这样的东西

USE [databaseName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[LogTrim]
                       (
                          @DaysToKeep             INT = 28
                          --@Blocks               INT = 1000 --??
                       )
AS
SET NOCOUNT ON
---------------------------------------------------------------------
-- Declarations
---------------------------------------------------------------------
-- Standard Variables
DECLARE
        @Error            INT
       ,@ErrorCode        INT
       ,@ExitCode         INT
       ,@ProcedureLineNbr INT
       ,@ProcedureName    VARCHAR(30)
       ,@rc               INT          
       ,@Rowcount         INT

-- Local Variables
DECLARE
         @DateToKeep       DATETIME
        ,@TimePeriodToKeep INT
        ,@DeletedRowCount  DEC
        ,@Message1         VARCHAR(60)
        ,@Message2         VARCHAR(60)
        ,@ERRPARAMETER     INT
        ,@ERRUNEXPECTED    INT

---------------------------------------------------------------------
-- Initializations
---------------------------------------------------------------------
-- Standard Variables
SELECT
        @ExitCode          = 0
       ,@ProcedureName     = OBJECT_NAME(@@PROCID)
       ,@ProcedureLineNbr  = 0

-- Local Variables
SET @TimePeriodToKeep      =  ABS( @DaysToKeep )
SET @DateToKeep            =  DATEADD( dd, -@TimePeriodToKeep, ( CONVERT( DATETIME, CONVERT( CHAR( 10 ), GETDATE( ), 120 ), 120 ) ) )
SET @ERRPARAMETER          =  200110
SET @ERRUNEXPECTED         =  200104

PRINT ( 'Oldest date to keep = ' + CONVERT( VARCHAR, @DateToKeep ) )
---------------------------------------------------------------------
---------------------------------------------------------------------
BEGIN TRANSACTION DeleteRows

DELETE
FROM
         tableName
WHERE
         CreateDate < @DateToKeep --TimeStart

SET @Rowcount = @@ROWCOUNT
SET @Error    = @@ERROR

IF ( @Error = 0 )
BEGIN  -- @Error = 0

    COMMIT TRANSACTION DeleteRows
    SET   @Message2 = 'Number of rows deleted = ' + CONVERT( VARCHAR, @Rowcount )
    PRINT @Message2

END  -- @Error = 0
ELSE
BEGIN  --  @Error <> 0

    SET @ErrorCode = @ERRUNEXPECTED
    SET @Message1  = CONVERT( VARCHAR, @Error ) + ' (Delete rows from EBCPDiagnosticLog)'
    RAISERROR( @ErrorCode, 16, 1, @ProcedureName, @Message1)
    ROLLBACK TRANSACTION DeleteRows
    GOTO ErrorHandler

END  --  @Error <> 0

---------------------------------------------------------------------
---------------------------------------------------------------------
GOTO ExitProc

---------------------------------------------------------------------
-- Error Handler
---------------------------------------------------------------------
ErrorHandler:
   SELECT @ExitCode =  -100
   GOTO ExitProc

---------------------------------------------------------------------
-- Exit Procedure
---------------------------------------------------------------------
ExitProc:
   RETURN (@ExitCode)
Run Code Online (Sandbox Code Playgroud)

现在修剪将同时删除所有数据。但我想添加一个名为 Blocks 的参数,它将根据输入参数或默认值 28 进行删除。谢谢。

小智 5

您可以使用WHILE循环,该循环将循环直到删除语句中的 @@ROWCOUNT 小于 1000(表明没有更多行可供删除)

DECLARE @delete_count int;
SET @delete_count = 1000;

WHILE (1=1)
BEGIN
    -- Delete the records
    DELETE 
        TOP (@delete_count)
    FROM
        dbo.EBCPDiagnosticLob
    WHERE
        CreateDate < @DateToKeep;

    -- If there are no more rows to delete, then break out of the loop
    IF (@@ROWCOUNT < @delete_count)
        BREAK;
END;
Run Code Online (Sandbox Code Playgroud)