PRINT-Anweisung in T-SQL

75

Warum scheint die PRINT-Anweisung in T-SQL nur manchmal zu funktionieren? Was sind die Einschränkungen bei der Verwendung? Es scheint manchmal, dass eine Ergebnismenge, wenn sie generiert wird, zu einer Nullfunktion wird. Ich habe angenommen, dass sie eine Beschädigung der Ergebnismenge verhindert. Könnte die Ausgabe jedoch nicht in einer anderen Ergebnismenge wie der Zeilenanzahl ausgehen?

ProfK
quelle
2
Könnten Sie ein Beispiel für einen Code geben, der manchmal gedruckt wird und manchmal nicht. Ich glaube nicht, dass ich die Frage verstehe.
RB.

Antworten:

113

Wenn Sie also eine Aussage wie die folgende haben, sagen Sie, dass Sie kein "Druck" -Ergebnis erhalten?

Wählen Sie * aus sysobjects
DRUCKEN 'Gerade ausgewählt * aus Sysobjekten'

Wenn Sie SQL Query Analyzer verwenden, sehen Sie unten zwei Registerkarten, von denen eine "Nachrichten" ist. Dort werden die "print" -Anweisungen angezeigt.
Wenn Sie sich Gedanken über den Zeitpunkt machen, zu dem die Druckanweisungen angezeigt werden, sollten Sie versuchen, so etwas wie zu verwenden

Raiserror ('My Print Statement', 10,1) mit nowait

Dadurch erhalten Sie die Nachricht sofort, wenn die Anweisung erreicht ist, anstatt die Ausgabe zu puffern, wie dies der Query Analyzer unter den meisten Bedingungen tut.

David T. Macknet
quelle
1
Cooler Deal. Ich bin froh, dass das für dich geklappt hat. Normalerweise fordere ich den Abfrageanalysator auf, mir eine Textausgabe zu geben, damit ich die Nachrichten inline sehen kann (Strg + T). Genießen!
David T. Macknet
1
Was sind die 10 und 1 Argumente im Raiserror-Beispiel?
Jon Schneider
Die 10, 1 sagen dem Server wirklich nur "hier gibt es nichts zu sehen". Unter docs.microsoft.com/en-us/sql/t-sql/language-elements/… finden Sie Einzelheiten zu deren tatsächlichen Bedeutungen.
David T. Macknet
1
Ist auf diese Weise RaiseErroridentisch PRINTmit Ausnahme des Timings?
FMFF
1
Ich glaube schon. Es kann den zusätzlichen Vorteil haben, dass der Puffer sofort ausgegeben wird, sodass auch andere Druckanweisungen angezeigt werden. Dies ist jedoch etwas, mit dem Sie spielen möchten, um dies zu überprüfen. Nach meinem Verständnis wird die Warteschlange sofort ausgegeben.
David T. Macknet
38

Die Print-Anweisung in TSQL ist eine missverstandene Kreatur, wahrscheinlich wegen ihres Namens. Es sendet tatsächlich eine Nachricht an den Fehler- / Nachrichtenbehandlungsmechanismus, der sie dann an die aufrufende Anwendung überträgt. PRINT ist ziemlich dumm. Sie können nur 8000 Zeichen (4000 Unicode-Zeichen) senden. Sie können eine Literalzeichenfolge, eine Zeichenfolgenvariable (varchar oder char) oder einen Zeichenfolgenausdruck senden. Wenn Sie RAISERROR verwenden, sind Sie auf eine Zeichenfolge von nur 2.044 Zeichen beschränkt. Es ist jedoch viel einfacher, damit Informationen an die aufrufende Anwendung zu senden, da eine Formatierungsfunktion aufgerufen wird, die der alten printf in der Standard-C-Bibliothek ähnelt. RAISERROR kann zusätzlich zur Textnachricht auch eine Fehlernummer, einen Schweregrad und einen Statuscode angeben und benutzerdefinierte Nachrichten zurückgeben, die mit der gespeicherten Systemprozedur sp_addmessage erstellt wurden.

Ihre Fehlerbehandlungsroutinen eignen sich nicht für den Empfang von Nachrichten, obwohl Nachrichten und Fehler so ähnlich sind. Die Technik hängt natürlich von der Art und Weise ab, wie Sie sich mit der Datenbank verbinden (OLBC, OLEDB usw.). Um Nachrichten vom SQL Server-Datenbankmodul zu empfangen und zu verarbeiten, müssen Sie bei Verwendung von System.Data.SQLClient einen SqlInfoMessageEventHandler-Delegaten erstellen, der die Methode identifiziert, die das Ereignis behandelt, um auf das InfoMessage-Ereignis zu warten in der SqlConnection-Klasse. Sie werden feststellen, dass Nachrichtenkontextinformationen wie Schweregrad und Status als Argumente an den Rückruf übergeben werden, da diese Nachrichten aus Systemsicht wie Fehler sind.

Es ist immer eine gute Idee, diese Nachrichten in Ihrer Anwendung abzurufen, selbst wenn Sie nur in eine Datei spoolen, da sie immer dann verwendet werden können, wenn Sie versuchen, ein wirklich dunkles Problem zu verfolgen. Ich kann jedoch nicht glauben, dass die Endbenutzer sie jemals sehen sollen, es sei denn, Sie können eine Informationsebene reservieren, die Inhalte in der Anwendung anzeigt.


quelle
26

Query Analyzer puffert Nachrichten. Die Anweisungen PRINT und RAISERROR verwenden beide diesen Puffer, aber die Anweisung RAISERROR verfügt über die Option WITH NOWAIT. Verwenden Sie zum sofortigen Drucken einer Nachricht Folgendes:

RAISERROR ('Your message', 0, 1) WITH NOWAIT

RAISERROR zeigt nur 400 Zeichen Ihrer Nachricht an und verwendet eine ähnliche Syntax wie die C printf-Funktion zum Formatieren von Text.

Bitte beachten Sie, dass durch die Verwendung von RAISERROR mit der Option WITH NOWAIT der Nachrichtenpuffer geleert wird, sodass auch alle zuvor gepufferten Informationen ausgegeben werden.

JimCarden
quelle
1
Die RAISERROR-Syntax war ein Schmerz, aber eine leere zu setzen, nachdem mein DRUCK die Arbeit erledigt hat, danke für die Info!
Cobusve
21

Ich bin kürzlich darauf gestoßen, und es endete damit, dass ich eine convert-Anweisung für eine Nullvariable hatte. Da dies zu Fehlern führte, wurde die gesamte print-Anweisung als null gerendert und überhaupt nicht gedruckt.

Beispiel - Dies wird fehlschlagen:

declare @myID int=null
print 'First Statement: ' + convert(varchar(4), @myID)

Beispiel - Dies wird gedruckt:

declare @myID int=null
print 'Second Statement: ' +  coalesce(Convert(varchar(4), @myID),'@myID is null')
WEFX
quelle
Nicht nur DRUCKEN: Die Verwendung des Operators + mit einem beliebigen Nullwert an einer beliebigen Stelle in T-SQL führt zu einer Null, unabhängig davon, ob andere Dinge miteinander verkettet werden mussten, die nicht null waren. Wenn Sie ISNULL (@myID, '') oder COALESCE verwenden, kann die Null mit Zeichenfolgen verkettet werden.
Troy
3

Für alle anderen, die diese Frage lesen und in ihrer Ausgabe wirklich Druckanweisungen fehlen, gibt es tatsächlich Fälle, in denen der Druck ausgeführt wird, aber nicht an den Client zurückgegeben wird. Ich kann dir nicht genau sagen, was sie sind. Ich kann Ihnen sagen, dass Sie eine go-Anweisung unmittelbar vor und nach einer print-Anweisung sehen, wenn sie ausgeführt wird.

JohnOpincar
quelle
Ich habe auch Fälle erlebt, in denen eine print-Anweisung erwartungsgemäß in das Nachrichtenfenster schreibt. Es passiert mir nach einem Commit oder einem Rollback.
Chris Simpson
Das Hinzufügen von GOAnweisungen hat mein PRINTs in die Shell gespült, was ich wollte
Matt Kemp
0

Haben Sie Variablen ausgegeben, die diesen Druckanweisungen zugeordnet sind? Wenn ja, habe ich festgestellt, dass die print-Anweisung nicht ausgegeben wird, wenn die Variable keinen Wert hat.

user2574678
quelle
Sie scheinen den Effekt der Verkettung NULLmit einer Zeichenfolge nicht zu verstehen . PRINT 'a' + CAST(NULL AS VARCHAR(MAX));verhält sich genau so, wie ich es erwarten würde.
Binki