C#到SQL ExecuteReader()卡住

时间:2017-06-14 18:56:39

标签: c# sql

在我的应用程序中运行以下方法时,应用程序冻结,当我暂停VS时,它似乎停留在线路上:

SqlDataReader reader = select.ExecuteReader();

我已经运行了其他SQL方法,所以我知道连接字符串是正确的,我已经仔细检查了SQL,那很好。我错了认为当调用ExecuteReader()时,reader变量不能包含标量函数的返回值吗?

public static bool AccountValidation(string username, string password)
{
    string statement = "select dbo.AccountValidation('" + username + "','" + password + "')";
    SqlCommand select = new SqlCommand(statement, connect);
    connect.Open();
    SqlDataReader reader = select.ExecuteReader();
    string result = reader.ToString();
    connect.Close();

    if (result != "true")
    {
        return false;
    }
    else
    {
        return true;
    }
}

3 个答案:

答案 0 :(得分:3)

主要问题是你实际上并没有从数据读取器读取任何内容,你必须遍历结果集然后根据序数/位置索引进行读取。

还有其他一些大问题,比如

  • 不使用让代码容易受到sql注入攻击的参数。
  • 未将您的一次性物品包裹在using块中,如果有例外,可能会打开数据库连接
  • 在您的类型中共享数据库连接。根据需要创建连接,然后在完成后处置它们。

以下是修补程序的更新代码。我猜测了列类型(varchar),修复了它们以及在模式中实现的长度。

public static bool AccountValidation(string username, string password)
{
    const string statement = "select dbo.AccountValidation(@username, @password)";
    string result = null;

    // reference assembly System.Configuration
    string connStr = System.Configuration.ConfigurationManager.ConnectionStrings["YourDb"].ConnectionString;

    using(var connection = new SqlConnection(connStr))
    using(SqlCommand cmd = new SqlCommand(statement, connect))
    {
        cmd.Parameters.Add(new SqlParameter("@username", SqlDbType.VarChar, 200){Value = username});
        cmd.Parameters.Add(new SqlParameter("@password", SqlDbType.VarChar, 200){Value = password});
        connect.Open();
        using(SqlDataReader reader = cmd.ExecuteReader())
        {
            if(reader.Read())
                result = reader.GetString(0); // read back the first column of the first row
        }
    }
    if (result != "true")
    {
        return false;
    }
    else
    {
        return true;
    }
}

另一方面,从数据库函数bit返回AccountValidation然后用reader.GetBoolean(0)读回来并将其分配给结果并直接返回进行字符串比较。

此外,正如上面评论中所述,如果您只返回1个值,则调用ExecuteScalar而不是ExecuteReader会更容易(而且代码更少)。

答案 1 :(得分:1)

添加行

reader.Read();
行前

string result = reader.ToString();

另外,请参数化您的查询。

答案 2 :(得分:0)

我没有足够的声誉留下评论,但是为了回答部分问题,是的,您可以使用SqlDataReader读取带或不带列别名的单个标量结果。