下面的函数旨在确定查询是否将返回任何行。在SQL中传递的是查询。如果导致错误,则函数应返回false。但是,当SQL =
SELECT TOP 1 [AU_ID]
FROM [dat].[model_80av2_v1_2941]
WHERE [AU_ID] IS NOT NULL AND convert(int, [AU_ID]) <> [AU_ID]
由于未检测到错误,因此该函数错误地返回true。但是,在SQL Management Studio中执行相同的查询会导致错误:
消息232,级别16,状态3,第3行
类型为int的算术溢出错误,值= -1000000000000000000000000000000000000.000000。
显然,该函数应该返回false,因为值不在int数据范围内,但错误处理未检测到错误。为什么?从其他帖子中,我的理解是
SqlDataReader reader = cmd.ExecuteReader()
应该导致错误。private bool GetIfExists(string SQL, out int ErrorNumber, out bool Exists)
{
bool IsSuccess = true;
ErrorNumber = 0;
Exists = false;
try
{
using (SqlConnection cnn = new SqlConnection(_connectionString))
{
try
{
cnn.Open();
using (SqlCommand cmd = cnn.CreateCommand())
{
cmd.CommandText = SQL;
cmd.CommandTimeout = _commandTimeout;
try
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
Exists = reader.HasRows;
}
}
catch (SqlException ex)
{
if (ex.Errors.Count > 0) ErrorNumber = ex.Errors[0].Number;
throw;
}
catch
{
throw;
}
}
}
catch
{
throw;
}
finally
{
cnn.Close();
}
}
}
catch
{
IsSuccess = false;
}
return IsSuccess;
}
最佳答案
从其他帖子中,我的理解是SqlDataReader reader =
cmd.ExecuteReader()应该导致错误。
这通常是正确的,除非在SQL Batch将行返回给客户端的错误发生期间。在使用完所有结果之前,可能不会引发该异常。这是因为SQL Server通过表格数据流协议(TDS)将结果流返回给客户端,并且结果集行在SQL Server返回的异常之前。在使用完所有前面的结果之前,客户端API不会看到并引发该错误。
下面是一种可以使用和丢弃剩余结果以确保引发异常的方法。
using (SqlDataReader reader = cmd.ExecuteReader())
{
Exists = reader.HasRows;
do
{
while (reader.Read()) { };
} while (reader.NextResult());
}
This article包括可能无法按预期引发SQL异常的其他情况。我要补充一点,您将看到SQL Server Management Studio使用相同的查询引发的错误,因为它将
FireInfoMessageEventOnUserErrors
SqlConnection属性设置为true而不是依赖于引发SqlException的情况,这在应用程序代码中通常不会执行(也不应该这样做)。是的。关于c# - SQLDataReader无法引发异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45010861/