簡體   English   中英

SQL Server:如何使用Cursor刪除記錄

[英]SQL Server: How to use Cursor to delete records

我們想要刪除表中的大量過時數據,但這會長時間鎖定表。 是否可以使用Cursor刪除,說,在while循環中每個事務一百條記錄?

我在哪里可以參考這個例子?

像這樣的東西:

DECLARE @stillgoing bit;
SET @stillgoing = 1;

WHILE @stillgoing = 1
BEGIN
  DELETE TOP (100) YourTableName
  WHERE IsObsolete = 1;

  IF @@ROWCOUNT = 0
      SET @stillgoing = 0;

  CHECKPOINT /* Will encourage the log to clear if it's in Simple recovery model */
END

編輯:這只適用於SQL 2005及以上版本。 正如我們剛剛學習的那樣是SQL 2000,這段代碼改為:

DECLARE @stillgoing bit
SET @stillgoing = 1

SET ROWCOUNT 100

WHILE @stillgoing = 1
BEGIN
  DELETE YourTableName
  WHERE IsObsolete = 1

  IF @@ROWCOUNT = 0
      SET @stillgoing = 0

  CHECKPOINT /* Will encourage the log to clear if it's in Simple recovery model */
END

並且......簡單恢復模型意味着日志將在檢查點上截斷,而不是僅在備份日志時截斷。

您可以提交循環中的每100(或1000或其他)記錄,釋放鎖並讓任何掛起的操作進入其中。否則,您將生成一個大於O(n ^ 2)時間的大型事務日志當它變大。 這個東西將占用實際花費的很大一部分,而不是實際刪除。 如果批量和提交,你更安全,回滾/日志文件不會像瘋了一樣增長,並且鎖是可管理的。

但是,如果您需要大量回滾作為選項,則有兩種選擇:

  • 等一會兒
  • 首先備份表,然后執行批量刪除
Declare MyPrimaryKey [SomeType]

Declare @MyCursor Cursor For 

Select MyPrimayKey from MyTable

Open @MyCursor

Fetch Next From @MyCursor

Into
  @MyPrimaryKey

WHILE @@FETCH_STATUS = 0

BEGIN
   WaitFor Delay '00:00:05'

   Begin Transaction

   DELETE From MyTable where MyPrimaryKey = @MyPrimaryKey

   Commit Transaction

   Fetch Next From @MyCursor

   Into
     @MyPrimaryKey
END

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM