2008-10-06 12 views
42

Gibt es in SQL Server 2005 eine Möglichkeit zum Löschen von Zeilen und die Angabe, wie viele tatsächlich gelöscht wurden?Zählen der Anzahl gelöschter Zeilen in einer gespeicherten SQL Server-Prozedur

Ich könnte eine select count(*) mit den gleichen Bedingungen tun, aber ich muss das absolut vertrauenswürdig sein.

Meine erste Schätzung war die @@ROWCOUNT Variablen zu verwenden - aber das ist nicht festgelegt, z.

delete 
from mytable 
where datefield = '5-Oct-2008' 

select @@ROWCOUNT 

liefert immer eine 0

MSDN schlägt die OUTPUT Konstruktion, z.B.

delete from mytable 
where datefield = '5-Oct-2008' 
output datefield into #doomed 

select count(*) 
from #doomed 

Dies schlägt tatsächlich mit einem Syntaxfehler fehl.

Irgendwelche Ideen?

Antwort

47

Sie SET NOCOUNT OFF versucht haben?

+0

Ich hatte gedacht, dass ich das versucht habe - aber anscheinend hatte ich nicht, weil es wie ein Zauber wirkte - danke. – Unsliced

+1

MSDN scheint zu sagen, dass SET NOCOUNT den Ausdruck auswirkt. Warum beeinflusst dies den '@@ ROWCOUNT'? Sollte es nicht immer die Anzahl der gelöschten Zeilen (im OP) zurückgeben? – noelicus

+0

*** Das ist Vermutung *** Ich denke es ist, weil die Einstellung von NOCOUNT dem System mitteilt, dass es die Zählungen nicht verfolgen muss, um die Dinge effizienter zu machen. – wcm

0

Temporäre Tabelle mit einer Spalte ID erstellen.

In die temporäre Tabelle einfügen und die zu löschenden IDs auswählen. Das gibt Ihnen Ihre Zählung.

aus Ihrer Tabelle streichen ID in (select id aus temporären Tabelle)

+1

Obwohl etwas, das funktionieren würde, ist der Overhead von so etwas eine Verschwendung. –

+0

Dies würde in der Tat eine schlechte Leistung geben, Abfrage würde mindestens 2 mal länger dauern, was eine beträchtliche Zeit sein könnte, wenn Sie viele Datensätze bearbeiten. Kreatives Denken obwohl! –

3

In Ihrem Beispiel sollte @@ROWCOUNT funktionieren - es ist eine richtige Möglichkeit, um eine Reihe von gelöschten Zeilen zu finden. Wenn Sie versuchen, etwas aus Ihrer Anwendung zu löschen, dann müssen Sie SET NOCOUNT ON

Nach MSDN @@ ROWCOUNT-Funktion aktualisiert auch verwenden, wenn SET NOCOUNT ON als SET NOCOUNT ist nur die Nachricht die nach der Ausführung erhalten beeinflusst .

Wenn Sie also versuchen, mit den Ergebnissen von @@ROWCOUNT aus beispielsweise ADO.NET zu arbeiten, dann sollte SET NOCOUNT ON definitiv helfen.

8

Ich verwende @@ ROWCOUNT für diesen genauen Zweck in SQL2000 ohne Probleme. Stellen Sie sicher, dass Sie diese Anzahl nicht versehentlich zurücksetzen, bevor Sie sie überprüfen (BOL: "Diese Variable wird von einer beliebigen Anweisung, die keine Zeilen zurückgibt, wie z. B. einer IF-Anweisung, auf 0 gesetzt)."

0

Aus Neugier, wie rufen Sie die Prozedur? (Ich nehme an, es ist eine gespeicherte Prozedur?). Der Grund, warum ich frage, ist, dass es einen Unterschied zwischen dem Rückgabewert einer gespeicherten Prozedur gibt (der in diesem Fall 0 wäre) und einem Rowset-Ergebnis - das in diesem Fall eine einzelne Zeile mit einer einzigen Spalte wäre. In ADO.Net würde ersterer durch einen Parameter und letzterer mit einem SqlDataReader angesprochen werden. Verstehen Sie vielleicht den Rückgabewert der Prozedur als Zeilenzählung?

+0

Das war Code an einer Stelle (aber ja, in einer gespeicherten Prozedur) - Ich löschte einige Daten und schrieb diese Tatsache dann in eine Statustabelle, so dass es nicht wirklich so war, dass ich über Rückgabewerte verwirrt war. – Unsliced

7

tun Nur soviel:

SET NOCOUNT off ; 
SELECT @p1 = @@ROWCOUNT 

wobei P1 den Ausgangsparameter Sie in der gespeicherten Prozedur. Hoffe es hilft.

1

Ich habe einen Fall gefunden, in dem Sie @@rowcount nicht verwenden können, wie wenn Sie die eindeutige Anzahl der Werte wissen möchten, die anstelle der Gesamtanzahl gelöscht wurden.In diesem Fall würden Sie folgendes zu tun haben:

delete from mytable 
where datefield = '5-Oct-2008' 
output deleted.datefield into #doomed 

select count(distinct datefield) 
from #doomed 

Die Syntaxfehler im OP war, weil output nicht deleted vor dem datefield Feldnamen enthalten waren.