Ich habe eine sehr lange gespeicherte Prozedur in SQL Server 2005, die ich zu debuggen versuche, und verwende dazu den Befehl 'print'. Das Problem ist, dass ich die Nachrichten erst am Ende meines Sprocs von SQL Server zurückerhalte. Ich möchte in der Lage sein, den Nachrichtenpuffer zu leeren und diese Nachrichten sofort während der Laufzeit des Sproc zu sehen, anstatt genau zu diesem Zeitpunkt Ende.
sql-server
tsql
printing
Erik Forbes
quelle
quelle
Antworten:
Verwenden Sie die
RAISERROR
Funktion:Sie sollten nicht alle Ihre Drucke vollständig durch Raiserror ersetzen. Wenn Sie irgendwo eine Schleife oder einen großen Cursor haben, tun Sie dies einfach ein- oder zweimal pro Iteration oder sogar alle paar Iterationen.
Außerdem: Ich habe RAISERROR zum ersten Mal unter diesem Link kennengelernt, den ich nun als endgültige Quelle für die Behandlung von SQL Server-Fehlern betrachte und der definitiv eine Lektüre wert ist:
http://www.sommarskog.se/error-handling-I.html
quelle
Aufbauend auf der Antwort von @JoelCoehoorn besteht mein Ansatz darin, alle meine PRINT-Anweisungen beizubehalten und ihnen einfach die RAISERROR-Anweisung zu folgen, um den Flush zu verursachen.
Beispielsweise:
Der Vorteil dieses Ansatzes besteht darin, dass die PRINT-Anweisungen Zeichenfolgen verketten können, während dies mit RAISERROR nicht möglich ist. (So oder so haben Sie die gleiche Anzahl von Codezeilen, wie Sie eine Variable deklarieren und festlegen müssten, die in RAISERROR verwendet werden soll).
Wenn Sie wie ich AutoHotKey oder SSMSBoost oder ein gleichwertiges Tool verwenden, können Sie einfach eine Verknüpfung wie "] flush" einrichten, um die RAISERROR-Zeile für Sie einzugeben. Dies spart Ihnen Zeit, wenn es sich jedes Mal um dieselbe Codezeile handelt, dh nicht angepasst werden muss, um bestimmten Text oder eine Variable aufzunehmen.
quelle
RAISERROR()
dies dieprintf()
String-Interpolation im Stil unterstützt . Zum Beispiel, wenn@MyVariableName
ein stringish Typ (zBVARCHAR(MAX)
,NVARCHAR(MAX)
usw.), können SieRAISERROR()
mit einer Zeile:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Ja ... Der erste Parameter der RAISERROR-Funktion benötigt eine NVARCHAR-Variable. Versuchen Sie also Folgendes:
ODER
quelle
Eine andere bessere Option besteht darin, sich nicht auf PRINT oder RAISERROR zu verlassen und einfach Ihre "print" -Anweisungen in eine ## Temp-Tabelle in TempDB oder eine permanente Tabelle in Ihrer Datenbank zu laden, wodurch Sie die Daten sofort über eine SELECT-Anweisung aus einem anderen Fenster sichtbar machen . Das funktioniert am besten für mich. Die Verwendung einer permanenten Tabelle dient dann auch als Protokoll für die Ereignisse in der Vergangenheit. Die print-Anweisungen sind praktisch für Fehler. Mithilfe der Protokolltabelle können Sie jedoch auch den genauen Fehlerpunkt anhand des zuletzt protokollierten Werts für diese bestimmte Ausführung ermitteln (vorausgesetzt, Sie verfolgen die Gesamtstartzeit der Ausführung in Ihrer Protokolltabelle).
quelle
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
in Ihrer ÜberwachungssitzungREAD UNCOMMITTED
Transaktion natürlich in eine andere Tabelle kopieren , aber Sie verpassen wahrscheinlich den Moment kurz zuvorROLLBACK
. Also löst es wahrscheinlich das "wie weit?" nicht das "Warum Rollback?"Nur als Referenz: Wenn Sie in Skripten (Stapelverarbeitung) und nicht in gespeicherten Prozeduren arbeiten , wird die Löschausgabe durch den Befehl GO ausgelöst, z
Im Allgemeinen lautet meine Schlussfolgerung wie folgt: Die Ausgabe der Ausführung des mssql-Skripts, die in der SMS-GUI oder mit sqlcmd.exe ausgeführt wird, wird bei der ersten GO-Anweisung oder bis zum Ende des Skripts in die Datei file, stdoutput, gui window geleert.
Das Spülen innerhalb der gespeicherten Prozedur funktioniert anders, da Sie GO nicht darin platzieren können.
Referenz: tsql Go-Anweisung
quelle
go
Löscht nicht nur die Ausgabe, sondern beendet den Stapel gemäß dem von Ihnen angegebenen Link. Alles, was Siedeclare
tun, wird verworfen und ist daher für das Debuggen nicht sehr nützlich.declare @test int print "I want to read this!" go set @test=5
wird, obwohl Sie einen Fehler behaupten,@test
ist undefiniert, weil es in einem neuen Stapel ist.