下面的函数旨在确定查询是否将返回任何行。在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/

10-12 12:37
查看更多