2012-01-19 36 views
3

我不断收到一个我不明白的错误。 必须声明标量变量“@varname”必须声明标量变量“@ UserName”

数十小时的研究,尝试了多种解决方案,但没有成功。

我的目标是创建一个使用2个文本框和一个按钮的登录页面,用于检查用户是否根据存储在Sql数据库中的信息退出。

这是我认为问题是来自:

private bool DBConnection(string userName, string password) 
{ 
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

    //string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName + 
    //     "'AND Password ='" + password + "'");   //REMOVED AS THIS IS PRONE TO SQL INJECTIONS 

    string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw"); 

    SqlCommand cmd = new SqlCommand(cmdString, conn); 

    cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName; 
    cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password; 

    DataSet loginCredentials = new DataSet(); 
    SqlDataAdapter dataAdapter; 

    try 
    { 
     if (conn.State.Equals(ConnectionState.Closed)) 
     { 
      conn.Open(); 

      dataAdapter = new SqlDataAdapter(cmdString, conn); 
      dataAdapter.Fill(loginCredentials); 

      conn.Close(); 

      if (loginCredentials != null) 
      { 
       if (loginCredentials.Tables[0].Rows.Count > 0) 
       { 
        return true; 
       } 
       else 
       { 
        lblMessage.Text = "Incorrect Username or Password"; 
        lblMessage.Visible = true; 
       } 
      } 
     } 
    } 
    catch (Exception err) 
    { 
     lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count; 
     lblMessage.Visible = true; 
     return false; 
    } 

    return false; 
} 

具体其中 “DataAdapter.Fill方法(loginCredentials);”正在执行。

注释掉的语句成功地使用正确的用户名和密码登录用户,但据我所知是不安全的,因为它容易sql注入,这就是为什么我想参数化sql语句。

错误截图如下: Error screenshot.

任何帮助,将不胜感激。

+0

,而不是'的DataAdapter =新SqlDataAdapter的(cmdString,康涅狄格州);' 使用'dataAdapter.SelectCommand = cmd;' –

+0

请不要将您的错误作为链接发布到其他地方。 至于现在不可用。因此它可以防止任何人查看它。 – Richard

+1

@Richard嗯。链接为我工作,但是,将img嵌入到问题中。至于说明理由,在当天你需要某些声望之前,你可以有图像的问题:) –

回答

2

编辑:你应该传递sqlcommand到dataAdapter,因为在你的情况下,sqlcommand(cmd)比单纯的commandtext和connectionstring有更多的信息。你的代码可能如下所示:

private bool DBConnection(string userName, string password) 
{ 
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 

//string cmdString = ("SELECT UserName, Password FROM Users WHERE UserName ='" + userName + 
//     "'AND Password ='" + password + "'");   //REMOVED AS THIS IS PRONE TO SQL INJECTIONS 

string cmdString = ("SELECT * FROM Users WHERE UserName = @uname AND Password = @pw"); 

SqlCommand cmd = new SqlCommand(cmdString, conn); 

cmd.Parameters.Add("uname", SqlDbType.VarChar).Value = userName; 
cmd.Parameters.Add("pw", SqlDbType.VarChar).Value = password; 

DataSet loginCredentials = new DataSet(); 
SqlDataAdapter dataAdapter; 

try 
{ 
    if (conn.State.Equals(ConnectionState.Closed)) 
    { 
     conn.Open(); 

     dataAdapter = new SqlDataAdapter(cmd); 
     dataAdapter.Fill(loginCredentials); 

     conn.Close(); 

     if (loginCredentials != null) 
     { 
      if (loginCredentials.Tables[0].Rows.Count > 0) 
      { 
       return true; 
      } 
      else 
      { 
       lblMessage.Text = "Incorrect Username or Password"; 
       lblMessage.Visible = true; 
      } 
     } 
    } 
} 
catch (Exception err) 
{ 
    lblMessage.Text = err.Message.ToString() + " Error connecting to the Database // " + cmd.Parameters.Count; 
    lblMessage.Visible = true; 
    return false; 
} 

return false; 
} 
+0

我遇到了同样的问题,经过大量研究后,我偶然发现了答案,它很有用。任何想法为什么调用新的SqlDataAccess(cmdString,conn)在这种特殊情况下不起作用? – makoshichi

+0

没有直接关系到这里的问题,但我有一个类似的问题与OleDbDataAdapter和搜索结果在这里领导。对于OleDb,SQL文本中的参数应该使用?字符作为位置占位符。如果SQL文本在SQL文本中使用@paramname参数并使用SQL Server,则可能会得到相同的“必须声明标量变量”错误 – Rattle

+1

“用您的代码替换为:”对于试图理解问题的人员非常没有帮助,特别是当代码块非常大时。 – Goose

2
cmd.Parameters.Add("@uname", SqlDbType.VarChar).Value = userName; 

注意@在uname前面。

+0

@参数中的字符是可选的。 – Mubarek

3

您需要将cmd传递给SqlDataAdapter构造函数,而不是cmdStringconn对象。

2

除了下面介绍的所有错误(或在这里;))..你正在传递一个命令行和一个连接到数据适配器,但你正在填写一个你不使用的命令参数。 )所以你有几个错误...

0

,最重要的是,第一次检查,如果某个值分配给特定的变量即

cmd.parameter.add(@YOUR_VARIABLE, sqlDbtype.TYPE).value = ValueYouwantToGIveToThatVariable;