C# SQL查询在c asp.net中始终返回-1作为结果

C# SQL查询在c asp.net中始终返回-1作为结果,c#,asp.net,sql-server-2008,C#,Asp.net,Sql Server 2008,在我的代码中,我总是将'user_id'的值设置为-1。查询中有什么错误吗 我还需要这个连接查询 using (SqlConnection con = new SqlConnection(connectionString)) { try { SqlCommand cmd; if (con.State ==

在我的代码中,我总是将'user_id'的值设置为-1。查询中有什么错误吗

我还需要这个连接查询

            using (SqlConnection con = new SqlConnection(connectionString))
            {
                try
                {
                    SqlCommand cmd;
                    if (con.State == ConnectionState.Closed)
                    {
                        con.Open();
                    }
                    var user = Page.User.Identity.Name;
                    cmd = new SqlCommand("select UserId from Users where UserName='"+user+"'", con);
                    var user_id=cmd.ExecuteNonQuery();
                    cmd = new SqlCommand("select Gender from UserDetails where userId='"+user_id+"'");
                    var gender = cmd.ExecuteNonQuery();
                    SqlDataReader rdr = cmd.ExecuteReader();
                    if (rdr.Read())
                    {

                    }
                }
                catch (Exception e) { }
            }
ExecuteOnQuery只返回插入、删除或更新的受影响记录数。对于所有其他类型的查询,它返回-1

你想要的是ExecuteScalar。请注意,查询的结果也可以为NULL DBNull.Value

应该使用ExecuteScalar而不是ExecuteNotQuery

ExecuteOnQuery:

它不会返回任何数据。 它与insert和update一起使用。 它只返回受影响的行数。 执行官:

它只返回一个值。 该值将作为第一列第一行的值。 执行者

它用于命令对象。 它通过select语句返回数据库给定的值。
正如MSDN所说,ExecuteOnQuery返回:

对于UPDATE、INSERT和DELETE语句,返回值为 受命令影响的行数。当触发器存在于 在插入或更新表时,返回值包括数字 受插入或更新操作和编号影响的行数 受一个或多个触发器影响的行数。对于所有其他类型的 语句,返回值为-1。如果发生回滚,则返回 值也为-1

在您的情况下,您需要确保使用ExecuteScalar方法,该方法返回查询结果的第一个值。您还应该使用查询参数,而不是将其作为文本传递,因为这会导致SQL注入

cmd = new SqlCommand("select UserId from Users where UserName= @user, con);
cmd.Parameters.AddWithValue("@user", user);
int user_id = Convert.ToInt32(cmd.ExecuteScalar()); //NOTE THAT YOU WILL ALWAYS HAVE TO CAST THE RESULT, AS IT RETURNS Object

首先,ExecuteOnQuery不返回任何结果。如果要返回单个值,请使用ExecuteScalar

其次,通过连接字符串来创建SQL语句,您很容易出现SQL注入和转换错误。谷歌搜索博比表。或者想象一下如果有人进来会发生什么;从用户中删除;-作为用户名

第三,如果要检索用户的详细信息,请不要执行两个单独的查询。使用连接,例如:

var query = "Select Gender from UserDetails d " +
            " inner Join Users on Users.UserId=d.UserID " + 
            " where UserName=@user";

var genderCmd=new SqlCommand(query);
genderCmd.Parameters.Add("@user",SqlDbType.NVarChar,30);

using (SqlConnection con = new SqlConnection(connectionString))
{
    con.Open();

    genderCmd.Connection=con;
    genderCmd.Parameters["@user].Value=user;
    var gender=(string)genderCmd.ExecuteScalar();
    return gender;
}
您可以将查询和命令存储在字段中,并根据需要重用它们,例如:

void InitializeCommands()
{
    var query = "Select Gender from UserDetails d " +
                " inner Join Users on Users.UserId=d.UserID " + 
                " where UserName=@user";

    _genderCmd=new SqlCommand(query);
    _genderCmd.Parameters.Add("@user",SqlDbType.NVarChar,30);

}

//....

public string GetGender(string user)
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        con.Open();

        genderCmd.Connection=con;
        genderCmd.Parameters["@user"].Value=user;
        var gender=(string)genderCmd.ExecuteScalar();
        return gender;
    }
}
您可以使用Open、ExecuteScalar的异步版本,以避免在等待服务器响应时阻塞线程,例如:

public Task<string> GetGender(string user)
{
    using (SqlConnection con = new SqlConnection(connectionString))
    {
        await con.OpenAsync();

        genderCmd.Connection=con;
        genderCmd.Parameters["@user"].Value=user;
        var gender=await genderCmd.ExecuteScalarAsync();
        return (string)gender;
    }
}

IO操作(如对数据库的调用)是在网络子系统级别使用IO完成端口处理的,而不是线程

尝试cmd.ExecuteScalar并将其强制转换为int或long,然后再分配给变量。如果不希望得到结果,则只应使用ExecuteNonQuery。在这种情况下,您可能需要ExecuteScalar还可用于防止sql注入attacks@SuprabhatBiswal为什么?你认为他们在这种情况下有什么好处?这不是SQL注入的保护,而是通过参数化查询实现的。这不是简单性、性能或可维护性。另外,请注意,在转换.Bobby表之前,您应该始终检查null/DBNull.Value的结果。字符串连接。SQL注入。不。假设人们会照样复制答案。创建一个正确参数化的查询,例如选择。。。用户名=@user,con;cmd.Parameters。AddWithValue@user使用者好的,谢谢你先生提供的有用的信息,这很有效。我从中学到了很多