SQL Server: как использовать курсор для удаления записей - PullRequest
4 голосов
/ 20 января 2010

Мы хотим удалить тонны устаревших данных в таблице, но это надолго заблокирует таблицу. Можно ли использовать курсор для удаления, скажем, ста записей за транзакцию в цикле while?

А где я могу обратиться к примеру?

Ответы [ 3 ]

2 голосов
/ 20 января 2010

Примерно так:

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

И ... Простая модель восстановления означает, что журнал будет усекаться на контрольных точках, а не только при резервном копировании журнала.

1 голос
/ 20 января 2010
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
1 голос
/ 20 января 2010

Вы можете фиксировать каждые 100 (или 1000, или что угодно) записей в цикле, снимая блокировку и позволяя любым ожидающим операциям получить свою работу. В противном случае вы генерируете огромный журнал транзакций, который съедает больше, чем O (n ^ 2) время, когда оно становится большим. Эта вещь будет занимать большую часть фактического затраченного времени вместо фактического удаления. Если вы пакетируете и делаете коммит, вы в большей безопасности, файлы отката / журнала не будут расти как сумасшедшие, а блокировки будут управляемыми.

Если, однако, вам нужен такой огромный откат в качестве опции, есть 2 варианта:

  • Подождите долго
  • Сначала сделайте резервную копию таблицы, а затем удалите пакет
...