2009-04-28 6 views
2

Comment supprimer N entrées les plus anciennes. Je suis limité à Sybase. J'ai besoin d'écrire une procédure stockée qui accepterait un nombre X et ne laisserait alors que X nouvelles entrées dans la table. Par exemple: Say ID est incrémenté automatiquement. Plus il est petit, plus cette entrée est ancienne.Supprimer N entrées les plus anciennes dans le tableau

ID Text 
========= 
1 ASD 
2 DSA 
3 HJK 
4 OIU 

J'ai besoin d'une procédure qui serait exécutée comme ceci.

execute CleanUp 2 

et le résultat sera

ID Text 
========= 
3 HJK 
4 OIU 

Répondre

3

Remarque: la syntaxe SQL Server, mais devrait fonctionner

Delete from TableName where ID in 
    (select top N ID from TableName order by ID) 

Si vous voulez que N soit un paramètre que vous devrez construire l'instruction chaîne et l'exécuter

declare @query varchar(4000) 
set @query = 'Delete from TableName where ID in ' 
set @query = @query + '(select top ' + @N + ' ID from TableName order by ID)' 
exec sp_executesql @query 
+0

voudrez peut-être que pour être « où ID PAS dans » - En l'état, vous supprimez les N enregistrements supérieurs plutôt que de supprimer tous les enregistrements sauf les n premiers. –

+0

Je pense que Sergej dit "Comment supprimer N entrées les plus anciennes". Est-ce que je me trompe? –

+0

Malheureusement, c'est assez lent, mais c'est probablement la seule chose à faire. –

1

J'aime l'option d'Eduardo mieux c'est la solution la plus simple, mais puisque Sergej mentionne qu'il est assez lent, voici une solution alternative:

Créer une procédure stockée qui effectue les opérations suivantes:

  1. Créer une table temporaire avec la même structure que la table d'origine.
  2. Insérez les N lignes supérieures dans la table temporaire.
  3. Tronque la table d'origine.
  4. Copiez les lignes de la table temporaire dans la table d'origine.

Généralement, cela sera beaucoup plus rapide, surtout si vous avez beaucoup de lignes dans la table.

0

Si vous avez un index clusterisé sur ID, vous pouvez exécuter une requête delete top en toute sécurité.

delete top 2 from TableName; 
+0

Non, ce n'est vraiment pas le cas. Un index clusterisé ne fournit aucune garantie d'ordre pour une déclaration.Le fait que, * par chance *, il semble fonctionner dans des cas simples ne signifie pas qu'il devrait être invoqué. –

+1

À partir du document précédemment lié: Lorsque vous utilisez top n avec supprimer, mettre à jour ou dans une vue, vous ne pouvez pas spécifier d'ordre. S'il existe un ordre implicite sur la table d'un index cluster, cet ordre s'applique, sinon, les résultats sont imprévisibles et peuvent être dans n'importe quel ordre. Je ne dirais pas que c'est par hasard si la documentation le spécifie. – brianegge

0

Je sais que c'est une vieille question, mais cela peut se faire sans la construction de la déclaration que le haut réponse dire, en utilisant un CTE:

WITH MyCTE AS 
(
    SELECT Field1, Field2, ROW_NUMBER() OVER (ORDER BY Field1 ASC) AS RowNum 
    FROM MyTable 
    WHERE Field2 = @WhatIWant 
) 
DELETE FROM MyCTE WHERE RowNum <= @NbRowsToDelete; 
Questions connexes