T-SQL WHERE 循环中的 BEGIN TRANSACTION 和 COMMIT 在删除记录时失败
T-SQL BEGIN TRANSACTION and COMMIT within a WHERE Loop fails when deleting records
以下代码旨在按月循环并删除 t运行sactions。但是,它没有按照我预期的方式执行。我期待在每次 DELETE 之后发生 COMMIT。
例程在 运行 超出日志 space 并回滚它删除的 t运行 操作的 ALL 时失败。 COMMIT
没有按照我预期的方式执行。为了控制日志 space,我假设循环中的 COMMIT
每个月都会删除 COMMIT
,因此,防止日志 space 过度填充。
DECLARE @MaxPostDate AS DATE = '2021-01-31'
DECLARE @MinPostDate AS DATE = '2019-07-01'
DECLARE @NbrOfMonthsToMaintain As INT = 13
WHILE @NbrOfMonthsToBeDeleted >= 0
BEGIN
SELECT @NbrOfTransactions = COUNT(*)
FROM [dbo].[Transaction] f
WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
PRINT 'Delete ' + FORMAT(@NbrOfTransactions,'N0') + ' transactions between '
+ CAST(@StartingDeleteDate As VARCHAR(20)) + ' AND '
+ CAST(EOMONTH(@StartingDeleteDate) AS VARCHAR(20))
BEGIN TRANSACTION
DELETE f
FROM [dbo].[Transaction] f
WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
AND f.[PostDate] <= @DeleteToDate
COMMIT TRANSACTION
INSERT INTO [app].[DataDeletionHistory](
[DataType]
,[Description]
,[DateDeleted]
,[MonthDeleted]
,[RowsDeleted])
SELECT 'Transactions' As DataType
,'Delete' As [Description]
,GetDate() AS DateDeleted
,@StartingDeleteDate AS MonthDeleted
,@NbrOfTransactions AS RowsDeleted
SET @StartingDeleteDate = DATEADD(m,1,@StartingDeleteDate)
SET @NbrOfMonthsToBeDeleted = @NbrOfMonthsToBeDeleted - 1
END;
结果如下:
Delete 15,183,513 transactions between 2019-07-01 AND 2019-07-31
(15183513 rows affected)
(1 row affected)
Delete 14,999,308 transactions between 2019-08-01 AND 2019-08-31
(14999308 rows affected)
(1 row affected)
Delete 14,292,165 transactions between 2019-09-01 AND 2019-09-30
(14292165 rows affected)
(1 row affected)
Delete 15,365,025 transactions between 2019-10-01 AND 2019-10-31
(15365025 rows affected)
(1 row affected)
Delete 14,576,586 transactions between 2019-11-01 AND 2019-11-30
(14576586 rows affected)
(1 row affected)
Delete 15,316,013 transactions between 2019-12-01 AND 2019-12-31
(15316013 rows affected)
(1 row affected)
Delete 15,453,046 transactions between 2020-01-01 AND 2020-01-31
(15453046 rows affected)
(1 row affected)
Delete 14,408,066 transactions between 2020-02-01 AND 2020-02-29
Msg 9002, Level 17, State 4, Line 50
The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION'.
Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION'.
Msg 3314, Level 21, State 3, Line 1
检查一下,
DECLARE @MaxPostDate AS DATE = '2021-01-31'
DECLARE @MinPostDate AS DATE = '2019-07-01'
DECLARE @NbrOfMonthsToMaintain As INT = 13
begin try
SET NOCount ON
SET XACT_ABORT ON
WHILE @NbrOfMonthsToBeDeleted >= 0
BEGIN
--SELECT @NbrOfTransactions = COUNT(*)
--FROM [dbo].[Transaction] f
--WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
set @StartingDeleteDate=EOMONTH(@StartingDeleteDate)
--BEGIN TRANSACTION
DELETE f
FROM [dbo].[Transaction] f
WHERE (f.[PostDate]>= @StartingDeleteDate AND f.[PostDate]<= @StartingDeleteDate)
--AND f.[PostDate] <= @DeleteToDate
--COMMIT TRANSACTION
@NbrOfTransactions =@@RowCount
PRINT 'Delete ' + FORMAT(@NbrOfTransactions,'N0') + ' transactions between '
+ CAST(@StartingDeleteDate As VARCHAR(20)) + ' AND '
+ CAST(@StartingDeleteDate AS VARCHAR(20))
INSERT INTO [app].[DataDeletionHistory](
[DataType]
,[Description]
,[DateDeleted]
,[MonthDeleted]
,[RowsDeleted])
SELECT 'Transactions' As DataType
,'Delete' As [Description]
,GetDate() AS DateDeleted
,@StartingDeleteDate AS MonthDeleted
,@NbrOfTransactions AS RowsDeleted
SET @StartingDeleteDate = DATEADD(m,1,@StartingDeleteDate)
SET @NbrOfMonthsToBeDeleted = @NbrOfMonthsToBeDeleted - 1
END
end try
begin catch
if(@@ROWCOUNT>0)
Rollback;
Throw;
end catch
您也可以使用 Output Deleted
来了解 count(*)
你也可以玩玩tblTransaction的Primary Key来做bulk delete或batch delete
以下代码旨在按月循环并删除 t运行sactions。但是,它没有按照我预期的方式执行。我期待在每次 DELETE 之后发生 COMMIT。
例程在 运行 超出日志 space 并回滚它删除的 t运行 操作的 ALL 时失败。 COMMIT
没有按照我预期的方式执行。为了控制日志 space,我假设循环中的 COMMIT
每个月都会删除 COMMIT
,因此,防止日志 space 过度填充。
DECLARE @MaxPostDate AS DATE = '2021-01-31'
DECLARE @MinPostDate AS DATE = '2019-07-01'
DECLARE @NbrOfMonthsToMaintain As INT = 13
WHILE @NbrOfMonthsToBeDeleted >= 0
BEGIN
SELECT @NbrOfTransactions = COUNT(*)
FROM [dbo].[Transaction] f
WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
PRINT 'Delete ' + FORMAT(@NbrOfTransactions,'N0') + ' transactions between '
+ CAST(@StartingDeleteDate As VARCHAR(20)) + ' AND '
+ CAST(EOMONTH(@StartingDeleteDate) AS VARCHAR(20))
BEGIN TRANSACTION
DELETE f
FROM [dbo].[Transaction] f
WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
AND f.[PostDate] <= @DeleteToDate
COMMIT TRANSACTION
INSERT INTO [app].[DataDeletionHistory](
[DataType]
,[Description]
,[DateDeleted]
,[MonthDeleted]
,[RowsDeleted])
SELECT 'Transactions' As DataType
,'Delete' As [Description]
,GetDate() AS DateDeleted
,@StartingDeleteDate AS MonthDeleted
,@NbrOfTransactions AS RowsDeleted
SET @StartingDeleteDate = DATEADD(m,1,@StartingDeleteDate)
SET @NbrOfMonthsToBeDeleted = @NbrOfMonthsToBeDeleted - 1
END;
结果如下:
Delete 15,183,513 transactions between 2019-07-01 AND 2019-07-31
(15183513 rows affected)
(1 row affected)
Delete 14,999,308 transactions between 2019-08-01 AND 2019-08-31
(14999308 rows affected)
(1 row affected)
Delete 14,292,165 transactions between 2019-09-01 AND 2019-09-30
(14292165 rows affected)
(1 row affected)
Delete 15,365,025 transactions between 2019-10-01 AND 2019-10-31
(15365025 rows affected)
(1 row affected)
Delete 14,576,586 transactions between 2019-11-01 AND 2019-11-30
(14576586 rows affected)
(1 row affected)
Delete 15,316,013 transactions between 2019-12-01 AND 2019-12-31
(15316013 rows affected)
(1 row affected)
Delete 15,453,046 transactions between 2020-01-01 AND 2020-01-31
(15453046 rows affected)
(1 row affected)
Delete 14,408,066 transactions between 2020-02-01 AND 2020-02-29
Msg 9002, Level 17, State 4, Line 50
The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION'.Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'MyDatabase' is full due to 'ACTIVE_TRANSACTION'.Msg 3314, Level 21, State 3, Line 1
检查一下,
DECLARE @MaxPostDate AS DATE = '2021-01-31'
DECLARE @MinPostDate AS DATE = '2019-07-01'
DECLARE @NbrOfMonthsToMaintain As INT = 13
begin try
SET NOCount ON
SET XACT_ABORT ON
WHILE @NbrOfMonthsToBeDeleted >= 0
BEGIN
--SELECT @NbrOfTransactions = COUNT(*)
--FROM [dbo].[Transaction] f
--WHERE f.[PostDate] BETWEEN @StartingDeleteDate AND EOMONTH(@StartingDeleteDate)
set @StartingDeleteDate=EOMONTH(@StartingDeleteDate)
--BEGIN TRANSACTION
DELETE f
FROM [dbo].[Transaction] f
WHERE (f.[PostDate]>= @StartingDeleteDate AND f.[PostDate]<= @StartingDeleteDate)
--AND f.[PostDate] <= @DeleteToDate
--COMMIT TRANSACTION
@NbrOfTransactions =@@RowCount
PRINT 'Delete ' + FORMAT(@NbrOfTransactions,'N0') + ' transactions between '
+ CAST(@StartingDeleteDate As VARCHAR(20)) + ' AND '
+ CAST(@StartingDeleteDate AS VARCHAR(20))
INSERT INTO [app].[DataDeletionHistory](
[DataType]
,[Description]
,[DateDeleted]
,[MonthDeleted]
,[RowsDeleted])
SELECT 'Transactions' As DataType
,'Delete' As [Description]
,GetDate() AS DateDeleted
,@StartingDeleteDate AS MonthDeleted
,@NbrOfTransactions AS RowsDeleted
SET @StartingDeleteDate = DATEADD(m,1,@StartingDeleteDate)
SET @NbrOfMonthsToBeDeleted = @NbrOfMonthsToBeDeleted - 1
END
end try
begin catch
if(@@ROWCOUNT>0)
Rollback;
Throw;
end catch
您也可以使用 Output Deleted
来了解 count(*)
你也可以玩玩tblTransaction的Primary Key来做bulk delete或batch delete