Connection.InfoMessage Ereignis

13/03/2009 - 01:48 von Lutz Elßner | Report spam
In SQL Prozeduren habe ich PRINT verwendet, um Meldungen auszugeben.
Ich behandle mit dem NET SqlClient das Connection.InfoMessage Ereignis.

So bekomme ich auch alle Meldungen zu sehen.

Aber manchmal kommen alle Meldungen in einem Ereignis und ich muss
SqlInfoMessageEventArgs.Errors durchlaufen, um jede einzeln zu bekommen.

Ein anderes Mal wird bei jeder einzelnen PRINT Anweisung ein einzelnes
Ereignis ausgelöst, das dann nur einen Error enthàlt.

Wovon hàngt das ab, ob die Meldungen gesammelt oder einzeln verschickt werden?

Ich habe beobachtet:
Wenn die Prozedur aus einem Trigger aufgerufen wird, kommen alle Meldungen in nur einem Event.
Wird die selbe Prozedur direkt aufgerufen, kommt jede Meldung einzeln.
Oder hat das was mit Transaction zu tun?
Oder mit ExecuteNonQuery / DataAdapter.Fill?

Ich würde gern die Meldungen gesammelt als SqlErrorCollection in nur einem Event bekommen.

Kann ich das beeinflussen?
Oder muss ich im NET Code selber sammeln, um nur einen Eintrag ins Protokoll zu bekommen?

Lutz
 

Lesen sie die antworten

#1 Elmar Boye
13/03/2009 - 09:49 | Warnen spam
Hallo Lutz,

Lutz Elßner schrieb:
In SQL Prozeduren habe ich PRINT verwendet, um Meldungen auszugeben.
Ich behandle mit dem NET SqlClient das Connection.InfoMessage Ereignis.

So bekomme ich auch alle Meldungen zu sehen.



Das sollte nur wàhrend der Entwicklung machen, denn im Dauereinsatz
verusacht das unnötigen Aufwand durch den zusàtzliche Netwerkverkehr.

Für einen Dauereinsatz solltest Du eher eine Tabelle verwenden,
in denen Du wichtige Schritte protokollieren kannst.

Aber manchmal kommen alle Meldungen in einem Ereignis und ich muss
SqlInfoMessageEventArgs.Errors durchlaufen, um jede einzeln zu bekommen.

Ein anderes Mal wird bei jeder einzelnen PRINT Anweisung ein einzelnes
Ereignis ausgelöst, das dann nur einen Error enthàlt.



Da der SQL Server sparsam ist, spart er Informationmeldungen auf
und schickt sie nur im Paket. Dazu gehören alle RAISERROR Meldungen
mit einem Schweregrad < 11 und PRINT, das wie ein RAISERROR mit dem
Schweregrad 0 behandelt wird.

Tritt ein "richtiger" Fehler ein, d. h. eine Meldung mit Schweregrad
11 oder höher, so werden auch alle anderen Meldungen verschickt,
um die Reihenfolge einzuhalten.
Meldungen mit Schweregrad 11 oder höher werden vom Treiber extra
behandelt und lösen eine SqlException aus.

Ebenso kommen sie am Ende der Anweisung, da sonst womöglich
keine Gelegenheit mehr besteht, sie zu versenden.

Wovon hàngt das ab, ob die Meldungen gesammelt oder einzeln verschickt
werden?



Wenn sowieso ein Paket verschickt werden muß, kommen auch
die Meldungen zum Zuge.

Ich habe beobachtet:
Wenn die Prozedur aus einem Trigger aufgerufen wird, kommen alle
Meldungen in nur einem Event.
Wird die selbe Prozedur direkt aufgerufen, kommt jede Meldung einzeln.
Oder hat das was mit Transaction zu tun?



Steht in der Prozedur ein SET NOCOUNT ON?
Wenn nicht, löst jede Anweisung eine Rückmeldung aus,
wo so nebenbei die Infomeldungen mitkommen.

Hast Du eine Anweisung die ein Ergebnis liefert (SELECT)
so kommen sie aber ebenso mit.

Oder mit ExecuteNonQuery / DataAdapter.Fill?



Die Clientbefehle haben weniger eine Bedeutung,
sondern was dabei wirklich über die Leitung geht.

Ich würde gern die Meldungen gesammelt als SqlErrorCollection
in nur einem Event bekommen.



Das kannst Du nicht beeinflussen.

Im Kern liegt es an der Struktur des TDS (Tabular Data Stream)
Protokolles, das - der Name deutet es an - darauf ausgelegt ist,
die Datenpakete möglichst effizient zu versenden.
Es wurde irgendwann in den 80er (von Sybase) entworfen und
geàndert wird daran nicht ohne Grund, denn dann würden àltere
Anwendungen womöglich nicht mehr richtig funktionieren.

Kann ich das beeinflussen?
Oder muss ich im NET Code selber sammeln, um nur einen Eintrag ins
Protokoll zu bekommen?



Wie eingangs schon geschrieben, schreibst Du es besser eine Tabelle.
Da kannst Du die Informationen abrufen, wann es Dir passt.
Nur aufràumen solltest Du von Zeit zu Zeit, wenn Du
viel protokollierst.

Gruß Elmar

Ähnliche fragen