2010-01-20 7 views
4

Nous voulons supprimer des tonnes de données obsolètes dans une table, mais cela verrouillera la table pendant longtemps. Est-il possible d'utiliser Cursor pour supprimer, dit, une centaine d'enregistrements par transaction dans un while-loop?SQL Server: comment utiliser Cursor pour supprimer des enregistrements

Et où puis-je me référer à l'exemple?

+2

Si la quantité de données que vous souhaitez conserver est petit et vous n'avez pas besoin des suppressions dans le journal des transactions, vous pourriez être mieux copier les données que vous souhaitez conserver une table temporaire, tronquer original tableau, puis en recopiant les données. – lins314159

+1

Thx la belle suggestion, mais c'est dangereux car il est en ligne et ne peut pas prédire quand les utilisateurs vont interroger cette table. BTW: la table a grandi à 4 Go. – Ricky

Répondre

2

Quelque chose comme ce:

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 

Modifier: Cela ne fonctionnera que dans SQL 2005 et sur. Comme nous venons d'apprendre qu'il est SQL 2000, ce code à la place:

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 

Et ... Modèle de récupération simple signifie que le journal tronque sur les points de contrôle, plutôt que lorsque le journal est sauvegardé.

+0

salut, qu'est-ce que tu veux dire par Simple Recovery Model. – Ricky

+0

hi Il semble ne pas fonctionner dans SQL 2000 – Ricky

+0

Salut, ne fonctionne toujours pas; Voici ma requête: SUPPRIMER TOP 100 XYZ WHERE DateCreated <= '2001/2/31' – Ricky

1

Vous pouvez valider tous les enregistrements 100 (ou 1000, ou peu importe) de la boucle, en libérant le verrou et en laissant les opérations en attente s'exécuter. Sinon, vous générez un journal de transactions volumineux supérieur à O (n^2) le temps quand il devient grand. Cette chose sera une grande partie du temps passé, au lieu d'obtenir la suppression effective. Si vous effectuez un lot et que vous vous engagez, vous êtes plus en sécurité, les fichiers de restauration/journalisation ne deviendront pas fous, et les verrous sont gérables.

Si toutefois vous avez besoin que énorme rollback en option, il y a 2 choix:

  • Patientez longtemps
  • sauvegarde la table d'abord, puis faire le lot supprime
1
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 
+0

Si vous publiez du code comme cet extrait T-SQL, sélectionnez ces lignes et utilisez le bouton "code" (101 010) dans la barre d'outils de l'éditeur ou appuyez sur Ctrl-K sur votre clavier pour formater correctement cette section. peut être affiché et syntaxiquement bien mis en évidence –

+0

Quelle est l'intention de WaitFor Delay? – Ricky

+0

l'attente de retard est de mettre en pause et permettre à d'autres transactions pour la table de commencer. –

Questions connexes