参数';?user_email';在集合中找不到

本文关键字:集合 找不到 user 参数 email | 更新日期: 2023-09-27 18:24:56

我正在使用MySql 5.6x和Visual Studio 2015,windows 10,64位。C#作为编程语言。在我的CRUD.cs(类文件)中,我创建了以下方法:

public bool dbQuery(string sql,string[] paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null){ 
         foreach(string i in paramList){
                string[] valus = i.Split(',');
                string p = valus[0];
                string v = valus[1];
                cmd.Parameters[p].Value = v;
            }
         }
        if (cmd.ExecuteNonQuery() > 0)
        {
            flag = true;
        }
    }
    catch (Exception exc)
    {
        error(exc);
    }
   }

我正在传递这样的查询和参数列表:

  protected void loginBtn_Click(object sender, EventArgs e)
  {
    string sql = "SELECT * FROM dept_login WHERE (user_email = ?user_email OR user_cell = ?user_cell) AND userkey = ?userkey";
    string[] param = new string[] {
         "?user_email,"+ userid.Text.ToString(),
         "?user_cell,"+ userid.Text.ToString(),
         "?userkey,"+ userkey.Text.ToString()
    };
    if (db.dbQuery(sql, param))
    {
        msg.Text = "Ok";
    }
    else
    {
        msg.Text = "<strong class='text-danger'>Authentication Failed</strong>";
    }
  }

现在的问题是,在循环迭代完成后,它直接跳到catch()块并生成一个异常:

Parameter '?user_email' not found in the collection.

我这样做是正确的发送这样的参数吗?还有其他方法可以做同样的事情吗?感谢

EDIT:我认为最好的方法可能是二维数组来收集参数及其值,然后在方法中循环以获取cmd中的参数。添加宽度值()?我可能错了。。。

参数';?user_email';在集合中找不到

dbQuery中,您没有使用期望的名称创建参数集合,因此当您尝试为不存在的参数设置值时会出现错误

public bool dbQuery(string sql,string[] paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null){ 
            foreach(string i in paramList){
                string[] valus = i.Split(',');
                string p = valus[0];
                string v = valus[1];
                cmd.Parameters.AddWithValue(p, v);
            }
        }
        if (cmd.ExecuteNonQuery() > 0)
           flag = true;
    }
    catch (Exception exc)
    {
        error(exc);
    }
}

当然,这将添加数据类型等于字符串的每个参数,因此如果数据表列不是字符串类型,则很容易出错

一个更好的方法是这个

List<MySqlParameter> parameters = new List<MySqlParameter>()
{
   {new MySqlParameter() 
        { 
           ParameterName = "?user_mail", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },
   {new MySqlParameter() 
        { 
           ParameterName = "?user_cell", 
           MySqlDbType= MySqlDbType.VarChar,
           Value = userid.Text
         },
   {new MySqlParameter() 
        { 
           ParameterName = "?userkey", 
           MySqlDbType = MySqlDbType.VarChar,
           Value = userkey.Text
         },
}
if (db.dbQuery(sql, parameters))
 ....

并且在dbQuery中接收将其添加到参数集合的列表

public bool dbQuery(string sql, List<MySqlParameter> paramList= null)
{
    bool flag = false;
    try
    {
        connect();
        cmd = new MySqlCommand(sql,con);
        cmd.Prepare();
        if(paramList != null)
         cmd.Parameters.AddRange(paramList.ToArray());
        if (cmd.ExecuteNonQuery() > 0)
        {
            flag = true;
        }
    }
    catch (Exception exc)
    {
        error(exc);
    }
}

顺便说一句,这与您的实际问题无关,但您的代码似乎没有关闭和处理连接。这将导致非常严重的问题需要诊断和解决。尝试使用using语句并避免全局连接变量

编辑正如您所注意到的,ExecuteNonQuery不适用于SELECT语句,您需要使用ExecuteReader并检查是否获得了一些返回值

    using(MySqlDataReader reader = cmd.ExecuteReader())
    {
        flag = reader.HasRows;
    }

当然,这意味着当您想要插入、更新或删除需要ExecuteNonQuery的记录时,您会遇到麻烦。创建一个通用函数来处理不同类型的查询非常困难,而且不值得进行所需的工作和调试。最好使用一些众所周知的ORM软件,如EntityFramework或Dapper。

您的SQL命令的参数集合不包含这些参数,因此您不能以这种方式对它们进行索引:cmd.Parameters[p].Value = v;您需要以以下方式将它们添加到Commands的Parameters集合:cmd.Parameters.AddWithValue(p, v);