为什么 SqlCommand.ExecuteNonQuery 抛出的 SqlException 包含所有 PRINT 作为错误?
当我运行以下代码片段时,
try
{
using (SqlConnection conn = new SqlConnection("I'm shy"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "PRINT 'A';PRINT 'B';PRINT 'C';RAISERROR('SQL_Error', 18, 1)";
cmd.ExecuteNonQuery();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
我收到以下消息:
SQL_Error
A
B
C
并且 ex.Errors
有 4 个条目(与打印相对应的 3 个 SqlError
有一个 SqlError. Class
of 0(相对于真正的错误为 18)
但是,如果我用 ExecuteScalar
替换 ExecuteNonQuery
,我会得到预期的结果:
消息为 SQL_Error
并且我在 ex.Errors
中只有一个条目...
有什么方法可以避免 cmd.ExecuteNonQuery
的奇怪行为?
When I run the following snippet
try
{
using (SqlConnection conn = new SqlConnection("I'm shy"))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = "PRINT 'A';PRINT 'B';PRINT 'C';RAISERROR('SQL_Error', 18, 1)";
cmd.ExecuteNonQuery();
}
}
}
catch (SqlException ex)
{
MessageBox.Show(ex.Message);
}
I get the following message:
SQL_Error
A
B
C
and ex.Errors
has 4 entries (The 3 SqlError
's corresponding to the prints have a SqlError.Class
of 0 (vs. 18 for the real error)
However, if I replace ExecuteNonQuery
with ExecuteScalar
, I get the expected result:
The message is SQL_Error
and I only have one entry in ex.Errors
...
Is there any way to avoid the strange behavior of cmd.ExecuteNonQuery
??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,你无法避免这种行为。它是 TdsParser.ThrowExceptionAndWarning() 编写方式的结果,
特别是这一行
我的猜测是,无论出于何种原因,集合 _error 或 _attentionErrors 之一对于 ExecuteScaler 来说是空的,而对于 ExecuteNonQuery 来说不是。
我相信,如果您足够深入地研究,您可能会找出原因。
无论如何,您似乎已经有了解决方法。仅使用 SQLExecption.Error 中的第一项
No you can't avoid this behavior. Its the result of the way TdsParser.ThrowExceptionAndWarning() is written
particularly this line
My guess is that for whatever reason one of the collection _error or _attentionErrors is empty for ExecuteScaler and its not for ExecuteNonQuery.
I'm sure if you poked around enough you could probably find out why.
In any case you seem to have the workaround already. Only use the first item in SQLExecption.Error
ExecuteNonQuery 通常返回记录集,而 ExecuteScalar 返回第一行+第一列。
ExecuteNonQuery normally returns a recordset while ExecuteScalar returns the first row + first column.