为什么我得到 "timeout" 和 "Cannot find table 0" 以及我可以采取哪些预防措施?

Why am I getting "timeout" and "Cannot find table 0" and what preventive measures are at my disposal?

在上一个问题的回答中,建议我也问一下这个相关问题。

偶尔,我的报告生成代码会抛出两个异常(它们不会向用户显示,而且他们认为一切都很正常),但我会通过电子邮件将它们发送给我。

第一个是,“超时已过。操作完成前超时时间已过或服务器未响应。

...此后总是紧随其后的是,“找不到 table 0

第一个异常消息认为下面方法中 try 部分 ("new SqlDataAdapter(cmd).Fill(ds);") 的最后一行代码抛出异常:

public static DataTable ExecuteSQLReturnDataTable(string sql, 
    CommandType cmdType, params SqlParameter[] parameters)
{
    using (var ds = new DataSet())
    {
        using (var connStr = new SqlConnection(CPSConnStr))
        {
            using (var cmd = new SqlCommand(sql, connStr))
            {
                cmd.CommandType = cmdType;
                cmd.CommandTimeout = EXTENDED_TIMEOUT;
                foreach (var item in parameters)
                {
                    cmd.Parameters.Add(item);
                }

                try
                {
                    cmd.Connection.Open();
                    new SqlDataAdapter(cmd).Fill(ds);
                }
                catch (Exception ex)
                {
                    RoboReporterConstsAndUtils.HandleException(ex);
                }
                return ds.Tables[0];
            }
        }
    }
}

第二条异常消息声称它来自上述方法中的最后一行重要行 ("return ds.Tables[0];")还有这个:

var dtFillRateResults =
    RoboReporterSQL.ExecuteSQLReturnDataTable
       (FILL_RATE_BY_DISTRIBUTOR_BY_CUSTOMER_STORED_PROC,
        CommandType.StoredProcedure,
            new SqlParameter()
            {
                ParameterName = "@Unit",
                SqlDbType = SqlDbType.VarChar,
                Value = _unit
            },
            new SqlParameter()
            {
                ParameterName = "@Member",
                SqlDbType = SqlDbType.VarChar,
                Value = _memberId
            },
            new SqlParameter()
            {
                ParameterName = "@BegDate",
                SqlDbType = SqlDbType.DateTime,
                Value = Convert.ToDateTime(_dateBegin)
            },
            new SqlParameter()
            {
                ParameterName = "@EndDate",
                SqlDbType = SqlDbType.DateTime,
                Value = Convert.ToDateTime(_dateEnd)
            }
    );

FILL_RATE_BY_DISTRIBUTOR_BY_CUSTOMER_STORED_PROC 是一个存储过程,在我在这里的努力和活动之前在其他地方使用过,所以不是 SP 本身导致了问题。

对于超级好奇的人,上面代码中的定制方法调用是:

public static DataTable ExecuteSQLReturnDataTable(string connectionStr,     
    string sql, CommandType cmdType, params SqlParameter[] parameters)
{
    using (var ds = new DataSet())
    {
        using (var connStr = new SqlConnection(connectionStr))
        {
            using (var cmd = new SqlCommand(sql, connStr))
            {
                cmd.CommandType = cmdType;
                cmd.CommandTimeout = EXTENDED_TIMEOUT;
                foreach (var item in parameters)
                {
                    cmd.Parameters.Add(item);
                }

                try
                {
                    cmd.Connection.Open();
                    new SqlDataAdapter(cmd).Fill(ds);
                }
                catch (Exception ex)
                {
                    RoboReporterConstsAndUtils.HandleException(ex);
                    return null;
                }
                return ds.Tables[0];
            }
        }
    }
}

错误是因为这里的填充或开放部分

try
{
    cmd.Connection.Open();
    new SqlDataAdapter(cmd).Fill(ds);
}

超时,但由于您处理了异常,执行最终命中了 return 语句,您试图从仍然为 null table 的 return a table ] 数据集的集合。

发生超时的原因有很多。可能需要更多信息,但是如果您在管理工作室中使用 sql 探查器,您应该能够了解连接是否打开、是否调用了 proc、它尝试 运行 的时间以及什么部分导致超时。如果它在其他地方有效,请捕获您的输入参数并直接尝试。

同时将超时设置为 0 应该会给您最大可能。