C# SQL查询在c asp.net中始终返回-1作为结果
在我的代码中,我总是将'user_id'的值设置为-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 ==
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使用者好的,谢谢你先生提供的有用的信息,这很有效。我从中学到了很多