【问题标题】:How to stop a query that is taking too long to process如何停止处理时间过长的查询
【发布时间】:2019-04-24 10:24:46
【问题描述】:

我有一个小程序,可以让学生测试他们在 ASP.Net 中构建并使用 SQL Server 数据库的 SQL 查询。问题是某些查询“挂起”控制台和 SQL Server。考虑到这一点,我想将执行时间限制为 10 秒或抛出异常。

现在代码看起来像这样:

        SqlCommand cmd = new SqlCommand();

        cmd.CommandText = TextBox1.Text; //Their query
        cmd.CommandType = CommandType.Text;
        cmd.CommandTimeout = 1;
        cmd.Connection = sqlConnection1;

        sqlConnection1.Open();
        try
        {
            GridView1.DataSource = cmd.ExecuteReader();
            GridView1.DataBind();
            int count = GridView1.Rows.Count;
            Label1.Text = count.ToString() + " Rows";
        }
        catch (Exception ex)
        {
            Label1.Text = ex.Message;
            GridView1.DataSource = null;
            GridView1.DataBind();
        }
        finally
        {
            sqlConnection1.Close();
        }

CommandtTimeout 不适合我,因为问题通常是查询不断流式传输行(主要是由于笛卡尔积运算)。

有没有办法在不遍历每一行的情况下停止查询中间执行?

【问题讨论】:

  • 我希望你真的信任你的用户。这不仅仅是普通的 SQL 注入,而是显式的 SQL 注入。你看过SqlConnection.​Connection​Timeout吗?
  • 这是在运行训练数据库的虚拟机上,用户只能执行选择语句。 SqlConnection.​Connection​Timeout 没有解决问题,因为他们尝试笛卡尔积查询并且 SQL Server 提供行。缓慢但肯定地。
  • 请注意,ASP 不同于 ASP.Net。

标签: c# asp.net sql-server


【解决方案1】:

您可以使用线程来检查timeout of the code

//Variables
string input;

//Code to run until time exceeds
Thread thread = new Thread(() => {
    input = Console.ReadLine();
});
thread.Start();

//Check if time exceeded
if (!thread.Join(TimeSpan.FromSeconds(10)))
{
    thread.Abort();
    throw new Exception("Time exceeded.");
}

【讨论】:

  • 请不要致电Thread.Abort()。即使您处理任何异常,它仍然会破坏运行时,这意味着剩余的线程可能无法正常运行。它应该只在强制应用程序关闭时使用。
【解决方案2】:

不使用GridView1.DataSource = cmd.ExecuteReader();GridView1.DataBind();,您将不得不编写代码以继续读取DataReader,直到您确定它花费了太长时间或已经读取了太多行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-15
    • 2011-01-09
    • 2022-07-19
    • 1970-01-01
    • 2022-08-04
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    相关资源
    最近更新 更多