SQL查询总是返回-1作为结果在c#asp.net

问题描述:

在我的代码中,我总是得到'user_id'的值为-1。在查询中有什么错误?SQL查询总是返回-1作为结果在c#asp.net

我也想加入查询。

  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) { } 
      } 
+2

尝试cmd.ExecuteScalar并在分配给var之前将其强制转换为int或long。 –

+1

如果你不期望结果,你应该只使用'ExecuteNonQuery'。在这种情况下,您可能需要'ExecuteScalar'。 - http://stackoverflow.com/questions/2974154/what-is-the-difference-between-executescalar-executereader-and-executenonquery – smoksnes

+1

[返回值 类型:System.Int32 受影响的行数。](https ://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executenonquery(v = vs.110).aspx) – rene

首先,ExecuteNonQuery不返回任何结果。如果你想返回一个值,使用ExecuteScalar。

其次,通过连接字符串来创建SQL语句,您很容易受到SQL注入和转换错误的影响。谷歌为“鲍比表”。或者想象一下,如果有人输入'; DELETE FROM Users;--作为用户名会发生什么情况。

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

var query = "Select Gender from UserDetails d " + 
      " inner Join Users on Users.UserId=d.UserID " + 
      " where [email protected]"; 

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 [email protected]"; 

    _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; 
    } 
} 

您可以使用公开赛的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操作。

+0

是的,谢谢先生你的有用信息,它的工作。我从这里学到很多东西 – user7415073

ExecuteNonQuery不返回任何东西,但受影响的记录进行插入,删除或更新的数量。它为所有其他类型的查询返回-1。你想要的是ExecuteScalar。请注意查询的结果也可以是NULLDBNull.Value)。

您应该使用ExecuteScalar而不是ExecuteNotQuery

的ExecuteNonQuery

  1. 它不会返回任何数据。
  2. 它与插入和更新一起使用。
  3. 它仅返回受影响的行数。

的ExecuteScalar

  1. 它仅返回一个值。
  2. 该值将第一列第一行的值。

的ExecuteReader

  1. 及其对命令的对象。
  2. 它通过select语句返回数据库给出的值。
+0

好解释。 – UJS

+0

很好e xplanation – user7415073

AS MSDN说的ExecuteNonQuery返回:

对于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 
+0

还要注意,在施放之前,你应该总是检查'null' /'DBNull.Value'的结果。 –

+0

鲍比桌子。字符串连接。 SQL注入。没有。假设人们会按原样复制答案。创建一个正确的参数化查询,例如'“SELECT ... UserName = @ user”,con); cmd.Parameters.AddWithValue(“@ user”,user);“'这仅仅是一行 –

+0

@PanagiotisKanavos的权利。编辑 – NicoRiff