这里我试图在SMO Ojects.In Sqlserver中使用innerexception捕获sql异常 我收到此错误消息
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.
但是使用此代码
catch (Exception ex)
{
ErrorFlag = true;
//ex.Source.ToString();
e2dInsertAndGenerateErrorLog(ex.InnerException.Message.ToString(), FileName, "CHECKINAPPLY", PathName, "ErrorLog.Err");
}
我得到了这个
The select list for the INSERT statement contains more items than the insert list.
我还需要缓存此行
Msg 121, Level 15, State 1, Procedure test_sp_syntaxtext, Line 124
有什么建议吗?
编辑:
StreamReader str = new StreamReader(FiletextBox.Text.ToString());
string 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);
答案 0 :(得分:8)
使用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.ToString());
}
答案 1 :(得分:1)
catch (SqlException ex) { ... }
答案 2 :(得分:1)
查看您在http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlexception.aspx
找到的属性您需要抓住SqlException
而不是任何例外。
答案 3 :(得分:1)
记录异常时,记录整个事物是个好主意,尤其是 stacktrace 。堆栈跟踪是最重要的部分。如果您只是记录ex.ToString()
,则不会丢弃该信息。
答案 4 :(得分:1)
答案 5 :(得分:1)
我再一次很迟,但答案看起来都不适合我。 OP上下文是SMO。使用SMO,SqlException
可以封装为ExecutionFailureException的内部异常。这就是为什么他在看InnerException
。
以下是我用于记录SqlException
详细信息的解决方案(如果存在Logger
为log4net ILog
)。
Catch block:
catch (Exception ex)
{
Logger.Error("Unhandled error", ex);
LogSqlErrors(ex);
}
LogSqlErrors
(注意最后一行,这是照顾内部异常的原因):
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 StringBuilder();
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.ToString());
}
LogSqlErrors(ex.InnerException);
}
不幸的是,如果你的sql命令字符串包含许多批次(使用go
分隔符,如SMO所支持的),这不会告诉你哪个sql批处理产生错误。 (错误行号是针对失败的批次计算的,不考虑先前批次的行数。)
我已经检查了ExecutionFailureException
的构建方式(在SMO版本12上使用反编译器):它可以存储此信息,但事实并非如此。所以你只能猜测。
此外,如果您使用ContinueOnError
选项,则会吞下错误(不会存储在任何地方)。好吧,如果SMO团队可以改进他们库中的异常处理,那就太好了。