364 Stimmen

SET NOCOUNT ON Verwendung

Inspiriert durch diese Frage wo es unterschiedliche Ansichten über SET NOCOUNT gibt...

Sollten wir SET NOCOUNT ON für SQL Server verwenden? Wenn nicht, warum nicht?

Was es bewirkt Edit 6, am 22. Juli 2011

Es unterdrückt die Meldung "xx Zeilen betroffen" nach jeder DML. Dies ist eine Ergebnismenge, und wenn sie gesendet wird, muss der Client sie verarbeiten. Es ist winzig, aber messbar (siehe Antworten unten)

Bei Triggern usw. erhält der Client mehrere "xx betroffene Zeilen", was bei einigen ORMs, MS Access, JPA usw. alle möglichen Fehler verursacht (siehe nachstehende Änderungen).

Hintergrund:

Die allgemein anerkannte beste Praxis (dachte ich bis zu dieser Frage) ist die Verwendung von SET NOCOUNT ON in Triggern und gespeicherten Prozeduren in SQL Server. Wir verwenden es überall, und ein kurzer Blick auf Google zeigt, dass auch viele SQL Server MVPs damit einverstanden sind.

Laut MSDN kann dies eine .net SQLDataAdapter .

Nun bedeutet dies für mich, dass der SQLDataAdapter auf völlig einfache CRUD-Verarbeitung beschränkt ist, weil er erwartet, dass die Meldung "n Zeilen betroffen" übereinstimmt. Also, ich kann nicht verwenden:

  • IF EXISTS, um Duplikate zu vermeiden (Meldung, dass keine Zeilen betroffen sind) Hinweis: mit Vorsicht zu verwenden
  • WHERE NOT EXISTS (weniger Zeilen als erwartet)
  • Herausfiltern trivialer Aktualisierungen (z. B. keine tatsächlichen Datenänderungen)
  • Führen Sie vorher einen Tabellenzugriff durch (z. B. Protokollierung)
  • Komplexität oder Denormlisierung ausblenden
  • usw.

In der Frage sagt marc_s (der sich mit SQL auskennt), dass man es nicht verwenden soll. Dies unterscheidet sich von dem, was ich denke (und ich halte mich auch für einigermaßen kompetent in SQL).

Es ist möglich, dass ich etwas übersehe (bitte weisen Sie mich auf das Offensichtliche hin), aber was denken Sie da draußen?

Hinweis: Es ist Jahre her, dass ich diesen Fehler gesehen habe, da ich SQLDataAdapter heutzutage nicht mehr verwende.

Bearbeitet nach Kommentaren und Fragen:

Edit: Weitere Gedanken...

Wir haben mehrere Clients: ein Client kann einen C# SQLDataAdaptor verwenden, ein anderer nHibernate aus Java. Diese können auf unterschiedliche Weise beeinflusst werden mit SET NOCOUNT ON .

Wenn Sie gespeicherte Prozeduren als Methoden betrachten, dann ist es schlechtes Benehmen (Anti-Pattern), davon auszugehen, dass eine interne Verarbeitung auf eine bestimmte Weise für Ihre eigenen Zwecke funktioniert.

Bearbeiten 2: a Trigger, der nHibernate bricht Frage , wobei SET NOCOUNT ON kann nicht eingestellt werden

(und nein, es handelt sich nicht um ein Duplikat von diese )

Edit 3: Noch mehr Informationen, dank meines MVP-Kollegen

Bearbeiten 4: 13. Mai 2011

Bricht Linq 2 SQL auch, wenn nicht angegeben?

Bearbeiten 5: 14 Jun 2011

Bricht JPA, Stored Proc mit Tabellenvariablen: Unterstützt JPA 2.0 SQL Server-Tabellenvariablen?

Bearbeiten 6: 15 Aug 2011

Das SSMS-Datengitter "Zeilen bearbeiten" erfordert SET NOCOUNT ON: Aktualisierungs-Trigger mit GROUP BY

Bearbeiten 7: 07 Mär 2013

Ausführlichere Informationen von @RemusRusanu:
Macht SET NOCOUNT ON wirklich einen so großen Unterschied in der Leistung aus?

1voto

Subhransu Panda Punkte 67

NOCOUNT EINSCHALTEN; Der obige Code stoppt die Nachricht, die von der SQL-Server-Engine nach der Ausführung des DML/DDL-Befehls für das vordere Ergebnisfenster erzeugt wird.

Warum wir das tun? Da die SQL-Server-Engine einige Ressourcen benötigt, um den Status abzurufen und die Nachricht zu generieren, wird dies als Überlastung der SQL-Server-Engine angesehen, so dass wir die Noncount-Meldung einschalten.

1voto

Ram Kumar Punkte 5
  • SET NOCOUNT ON- Es wird "Befehl(e) erfolgreich abgeschlossen" angezeigt.
  • SET NOCOUNT OFF- es wird "(Anzahl der betroffenen Zeile(n))" angezeigt.

0voto

KRules Punkte 1

Ich weiß, dass die Frage ziemlich alt ist, aber ich wollte sie nur aktualisieren.

Am besten verwenden Sie "SET NOCOUNT ON" als erste Anweisung in Ihrer SP und setzen es kurz vor der letzten SELECT-Anweisung wieder auf OFF.

0voto

user__42 Punkte 492

SET NOCOUNT ON erlaubt sogar den Zugriff auf die betroffenen Zeilen wie diese:

SET NOCOUNT ON

DECLARE @test TABLE (ID int)

INSERT INTO @test
VALUES (1),(2),(3)

DECLARE @affectedRows int = -99  

DELETE top (1)
  FROM @test
SET @affectedRows = @@rowcount

SELECT @affectedRows as affectedRows

Ergebnisse

affectedRows

1

Nachrichten

Befehle erfolgreich abgeschlossen.

Fertigstellungszeit: 2020-06-18T16:20:16.9686874+02:00

-1voto

Rabia Mansour Punkte 1

Da ich nicht weiß, wie ich SET NOCOUNT ON zwischen Client und SQL testen kann, habe ich ein ähnliches Verhalten für den anderen SET-Befehl "SET TRANSACTION ISOLATION LEVEL READ UNCIMMITTED" getestet

Ich habe von meiner Verbindung aus einen Befehl gesendet, der das Standardverhalten von SQL (READ COMMITTED) ändert, und dieser wurde für die nächsten Befehle geändert. Als ich die ISOLATION-Ebene innerhalb einer gespeicherten Prozedur änderte, änderte sich das Verbindungsverhalten für den nächsten Befehl nicht.

Aktuelle Schlussfolgerung,

  1. Das Ändern der Einstellungen innerhalb der gespeicherten Prozedur ändert nicht die Standardeinstellungen der Verbindung.
  2. Das Ändern der Einstellung durch Senden von Befehlen über die ADOCOnnection ändert das Standardverhalten.

Ich denke, dies gilt auch für andere SET-Befehle wie "SET NOCOUNT ON".

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X