Wenn Sie einen Sicherungsbefehl innerhalb einer gespeicherten Prozedur ausgeben, die einen try catch und eine dynamische SQL verwendet, sind die Fehlermeldungen im Vergleich zur direkten Ausführung des Sicherungsbefehls sehr allgemein.
Try / Catch in SP:
begin try
execute sp_executesql @sql; -- a backup command
end try
begin catch
print ERROR_MESSAGE(); -- save to log, etc.
end catch
Ergebnisse in
50000: usp_Backup: 117: BACKUP DATABASE wird abnormal beendet.
wheareas, die den rohen Befehl ausgeben:
backup DATABASE someDb to disk...
Ergebnisse in besseren Details:
Suchfehler - SQL Server-Datenbankfehler: In der Datei "H: \ Ordnername \ Dateiname.bak:" 112 ist ein nicht behebbarer E / A-Fehler aufgetreten. 112 (Auf der Festplatte ist nicht genügend Speicherplatz vorhanden.)
Gibt es eine Möglichkeit, diese Details in Variablen innerhalb der gespeicherten Prozedur zu erfassen (protokollieren, an den Aufrufer zurückgeben, um die Logik erneut zu versuchen)? Es scheint, dass die Details auf dem Nachrichtenkanal durchkommen, aber ich möchte, dass sie im SP verfügbar sind.
quelle
Antworten:
Wenn
BACKUP DATABASE
ein Fehler generiert wird, werden tatsächlich zwei generiert. LeiderTRY/CATCH
ist es nicht möglich, den ersten Fehler zu erfassen. es erfasst nur den zweiten Fehler.Ich vermute, dass Ihre beste Möglichkeit, den wahren Grund für eine fehlgeschlagene Sicherung zu erfassen, darin besteht, Ihre Sicherungen über SQLCMD (mit
-o
Ausgabe an eine Datei), SSIS, C #, PowerShell usw. zu automatisieren . All dies gibt Ihnen eine viel bessere Kontrolle über die Erfassung aller Sicherungen der Fehler.Die SO-Antwort im Kommentar schlägt die Verwendung vor
DBCC OUTPUTBUFFER
- obwohl dies möglich ist, scheint dies überhaupt kein Kinderspiel zu sein. Fühlen Sie sich frei, Spaß mit diesem Verfahren von Erland Sommarskogs Website zu haben , aber dies scheint in Kombination mit immer noch nicht gut zu funktionierenTRY/CATCH
.Die einzige Möglichkeit, mit der ich die Fehlermeldung erfassen konnte, bestand darin,
spGET_LastErrorMessage
den tatsächlichen Fehler auszulösen. Wenn Sie es in einTRY/CATCH
einpacken, wird der Fehler verschluckt und die gespeicherte Prozedur führt nichts aus:In SQL Server <2012 können Sie den Fehler nicht selbst erneut auslösen, in SQL Server 2012 und höher jedoch. Diese beiden Varianten funktionieren also:
Oder ab 2012 funktioniert dies, macht aber den Zweck von weitgehend zunichte
TRY/CATCH
, da der ursprüngliche Fehler immer noch ausgelöst wird:In beiden Fällen wird der Fehler natürlich immer noch auf den Client übertragen. Wenn Sie dies verwenden
TRY/CATCH
, um dies zu vermeiden, müssen Sie leider eine Entscheidung treffen, es sei denn, es gibt eine Lücke, an die ich nicht denke. Geben Sie dem Benutzer entweder den Fehler und können Sie Details darüber erfassen es, oder unterdrücken Sie sowohl den Fehler als auch den tatsächlichen Grund.quelle
Nun, ich weiß, dass dies ein alter Thread ist, und ich weiß, dass ich einen verschlungenen Hack vorschlagen werde, aber nur für den Fall, dass er jemandem helfen kann, geht es so: Da diese Sicherungsfehler protokolliert werden, können Sie xp_readerrorlog im catch verwenden Block, um das Protokoll nach verwandten Nachrichten (Fehler oder Informationen) zu durchsuchen. Sie können nach xp_readerrorlog-Parametern suchen, aber kurz gesagt, Sie können eine Suchzeichenfolge und einen Startzeitfilter angeben, die in diesem Fall nützlich sind. Ich bin mir nicht sicher, ob dies Ihrer Wiederholungslogik helfen würde, aber um entweder Informationen oder Fehler für die Protokollierung zu erfassen, habe ich mir so etwas ausgedacht ...
HTH
quelle
Sie können die Fehlerdetails in einer Tabelle protokollieren. Sie können auch eine Protokolldatei erstellen, für die jedoch möglicherweise eine CLR oder xp_cmdshell erforderlich ist. Sie können auch Datenbank-E-Mails senden, dies kann jedoch zu Spam-Problemen führen und ist kein ordnungsgemäßes Protokoll.
Die Tabelle ist am einfachsten.
Schauen Sie sich das Beispiel von Jeremy Kadlec an, das Sie unter dem folgenden Link finden:
http://www.mssqltips.com/sqlservertip/1152/standardized-sql-server-error-handling-and-centralized-logging/
quelle
CATCH
. Dies liegt daran, dass nur die letzte Fehlermeldung inERROR_MESSAGE()
...