Ici, j'ai essayé d'attraper l'exception sql en utilisant innerexception dans SMO Ojects.In Sqlserver je reçois ce message d'erreur
Msg 121, Level 15, State 1, Procedure test_sp_syntaxtext, Line 124 The select list for the INSERT statement contains more items than the insert list.
Mais en utilisant ce code
catch (Exception ex) { ErrorFlag = true; //ex.Source.ToSsortingng(); e2dInsertAndGenerateErrorLog(ex.InnerException.Message.ToSsortingng(), FileName, "CHECKINAPPLY", PathName, "ErrorLog.Err"); }
je reçois ceci
The select list for the INSERT statement contains more items than the insert list.
Je dois mettre en cache cette ligne aussi
Msg 121, Level 15, State 1, Procedure test_sp_syntaxtext, Line 124
Toute suggestion?
MODIFIER:
StreamReader str = new StreamReader(FiletextBox.Text.ToSsortingng()); ssortingng script = str.ReadToEnd(); str.Dispose(); SqlConnection conn = new SqlConnection("Data Source=xx;database=xxx;User id=sx;Password=xxxx"); Server server = new Server(new ServerConnection(conn)); server.ConnectionContext.ExecuteNonQuery(script);
Utilisez SQLException .
catch (SqlException ex) { for (int i = 0; i < ex.Errors.Count; i++) { errorMessages.Append("Index #" + i + "\n" + "Message: " + ex.Errors[i].Message + "\n" + "LineNumber: " + ex.Errors[i].LineNumber + "\n" + "Source: " + ex.Errors[i].Source + "\n" + "Procedure: " + ex.Errors[i].Procedure + "\n"); } Console.WriteLine(errorMessages.ToSsortingng()); }
catch (SqlException ex) { ... }
Jetez un coup d'oeil aux propriétés que vous findez à http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.aspx
Vous aurez besoin d'attraper le SqlException
au lieu de n'importe quelle exception.
Lors de la journalisation d'une exception, il est judicieux de consigner tout le contenu , en particulier la stack . Le stacktrace est la partie la plus importante. Si vous venez de vous connecter à ex.ToSsortingng()
vous ne supprimerez pas cette information.
Essayer
catch (SqlException ex) { }
au lieu de catch (Exception ex) { }
.
Jetez un oeil aux informations MSDN sur SqlException.
Encore une fois, je suis très en retard, mais aucune des réponses ne me semble juste. Le context OP est SMO. Avec SMO, SqlException
peut être encapsulé en tant qu'exceptions internes de ExecutionFailureException. C'est pourquoi il regarde InnerException
.
Voici la solution que j'utilise pour SqlException
détails SqlException
si présents (avec Logger
étant un logognet ILog
).
Bloc de saisie:
catch (Exception ex) { Logger.Error("Unhandled error", ex); LogSqlErrors(ex); }
LogSqlErrors
(notez la dernière ligne, c'est ce qui s'occupe de l'exception interne):
private static void LogSqlErrors(Exception ex) { if (ex == null) return; var sqlEx = ex as SqlException; if (sqlEx != null && sqlEx.Errors != null && sqlEx.Errors.Count > 0) { var sqlErrs = new SsortingngBuilder(); sqlErrs.AppendFormat("SqlException contains {0} SQL error(s):", sqlEx.Errors.Count) .AppendLine(); foreach (SqlError err in sqlEx.Errors) { sqlErrs.AppendLine("--------------------------------") .AppendFormat("Msg {0}, Level {1}, State {2}, Procedure '{4}', Line {5}", err.Number, err.Class, err.State, err.Procedure, err.LineNumber) .AppendLine() .AppendLine(err.Message); } Logger.Warn(sqlErrs.ToSsortingng()); } LogSqlErrors(ex.InnerException); }
Malheureusement, si votre string de commands sql contient de nombreux lots (en utilisant des séparateurs de go
, tels que supportés par SMO), cela ne vous indiquera pas quel est le batch SQL qui génère l'erreur. (Le numéro de ligne d'erreur est calculé pour le lot défaillant, sans tenir count du nombre de lignes des lots précédents.)
J'ai vérifié la façon dont ExecutionFailureException
est construit (en utilisant un décompilateur sur SMO version 12): il aurait pu stocker cette information, mais ce n'est pas le cas. Donc vous ne pouvez que deviner.
De plus, si vous utilisez l'option ContinueOnError
, les erreurs sont avalées (pas stockées n'importe où). Eh bien, ce serait génial si l'équipe SMO pouvait améliorer le traitement des exceptions dans sa bibliothèque.