程序中提示:
System.Data.SqlClient.SqlException: 被准备语句 '(@UserID nvarchar(20),@UserPassword nvarchar(20))SELECT UserName' 需要参数 @UserID,但未提供该参数。代码片段如下:
public string Login(string _UserID,string _UserPassword)
{
SqlDbProvider data = new SqlDbProvider();
SqlParameter[] parms = {
   new SqlParameter("@UserID",SqlDbType.NVarChar,20,_UserID),
   new SqlParameter("@UserPassword",SqlDbType.NVarChar,20,_UserPassword)
   };
string UserName = null;
SqlDataReader dr = null;
dr = data.GetDataReader(SQL_SELECT_USER,parms);
if(dr.Read())
{
UserName = dr["UserName"].ToString();
}
return UserName;
}……SqlDbProvider.cs文件中 SqlDbProvider类
public SqlDataReader GetDataReader(string sqlString,SqlParameter[] parms)
{
SqlCommand cmd = new SqlCommand(sqlString,GetConnection());
cmd.Parameters.Clear();
foreach(SqlParameter parm in parms)
{
cmd.Parameters.Add(parm);
}
SqlDataReader dr = null;
dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
return dr;
}已经确定 _UserID,_UserPassword都有值传递进来,数据库连接正常,另一处调用ExecuteNonQuery方法提交数据却完全正常,为什么呢?

解决方案 »

  1.   

    我只知道conn关闭,reader里面的数据就会丢失。建议使用dataset,虽然占用内存多了一点。
      

  2.   

    可能问题就是不能返回datareader。
      

  3.   

    SQL_SELECT_USER 的内容是什么?
      

  4.   

    private const string SQL_SELECT_USER = "SELECT UserName FROM UserInfo WHERE UserID=@UserID AND UserPassword=@UserPassword";
      

  5.   

    在这个位置加断点调试看看foreach(SqlParameter parm in parms)
    {
    cmd.Parameters.Add(parm);
    }
      

  6.   

    能否把dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);这句改一改 不要用
    CommandBehavior.CloseConnection这种方式 因为我感觉它传完数据就关闭连接了 用dataReader时一个要注意的问题就是不能关闭连接.当连接不需要时在 Login(string _UserID,string _UserPassword) 函数中
    if(dr.Read())
    {
       UserName = dr["UserName"].ToString();
    }
    return UserName;
    加一句 dr.close(); 也就是说在调用程序中关闭连接
      

  7.   

    加断点调试了dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);在这句报错
      

  8.   

    dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);把这句改成dr = cmd.ExecuteReader();也不行,我已经从抓狂到平静了,呵呵,不知道哪里错了
      

  9.   

    改写一下方法再试试吧
    public SqlDataSet GetDataSet(string sqlString,SqlParameter[] parms)
    {}
      

  10.   

    以前正常的CommandExecuteNonQuery方法,现在也报同样的错误了,是什么地方的代码有错误呢?public int CommandExecuteNonQuery(string sqlString,SqlParameter[] parms)
    {
    SqlCommand cmd = new SqlCommand(sqlString,GetConnection());
    cmd.Parameters.Clear();
    foreach(SqlParameter parm in parms)
    {
    cmd.Parameters.Add(parm);
    }
    return cmd.ExecuteNonQuery();
    }
      

  11.   

    为什么不在这儿调试呢?主要是看看 parm加进去了没有                          
    foreach(SqlParameter parm in parms)
    {
    cmd.Parameters.Add(parm);
    }
      

  12.   

    To: charles_y(难得糊涂) 
    已经加断点了
    foreach(SqlParameter parm in parms)
    {
    cmd.Parameters.Add(parm);
    }
    正常通过,如何确定是否加进去了呢?看Parameter值为“未确定”……是不是参数赋值的问题啊?这样赋值哪不对呢?
      

  13.   

    原来确实是不能这样赋值啊SqlParameter[] parms = {
       new SqlParameter("@UserID",SqlDbType.NVarChar,20,_UserID),
       new SqlParameter("@UserPassword",SqlDbType.NVarChar,20,_UserPassword)
       };加下如下就通过了:
    parms[0].Value = _UserID;
    parms[1].Value = _UserPassword;
      

  14.   

    try
    {
    dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
    }
    catch(Exception ex)
    {
    MessageBox.Show(ex.Message.Tostring());
    }看看出错误提示
      

  15.   

    原来确实是不能这样赋值啊SqlParameter[] parms = {
       new SqlParameter("@UserID",SqlDbType.NVarChar,20,_UserID),
       new SqlParameter("@UserPassword",SqlDbType.NVarChar,20,_UserPassword)
       };加下如下就通过了:
    parms[0].Value = _UserID;
    parms[1].Value = _UserPassword;
    通过了
    通过了
    通过了
    通过了
    通过了
    通过了通过了通过了
      

  16.   

    原来用datareader的时候多,不过现在用dataview和dataset
      

  17.   

    我一直都这样付值的:SqlParameter[] parms = {
       new SqlParameter("@UserID",SqlDbType.NVarChar,20),
       new SqlParameter("@UserPassword",SqlDbType.NVarChar,20)
       };
    parms[0].Value = _UserID;
    parms[1].Value = _UserPassword;
      

  18.   

    不好
    不能防止注入攻击,而且代码不合理,名称也不合理 Check_Login.cs:
    namespace DataBase
    {
        public class CommonUtility
        {
            public static bool Check_Login(string User_Name,string Pass_Word)
            {
                Conn_DB Connection = new Conn_DB();
                
                string Sql = "Select * From Control Where UserName=@UserName And PassWord= @Password";
                SqlCommand Check_Login_Cmd = new SqlCommand(Sql, Connection.Conn);
                Check_Login_Cmd .Parameters.Add( new SqlParameter("@UserName",SqlDbType.Char,30));//其中30为数据字段的长度
     Check_Login_Cmd .Parameters.Add( new SqlParameter("@Password",SqlDbType.Char,30));//其中30为数据字段的长度
       Check_Login_Cmd.SqlParameter["@UserName"].Value=User_Name;
       Check_Login_Cmd.SqlParameter["@PassWord"].Value=Pass_Word;
                Connection.DB_Open();
                SqlDataReader SDR = Check_Login_Cmd.ExecuteReader();
                Connection.DB_Close(); //if exist
                if( SDR.Read())
                 return true;
                else 
                return false
            }
        }
    }
    页面调用:
    protected void Btn_Check_Login_Click(object sender, EventArgs e)
        {
            string UserName=this.TB_UserName.Text.ToString();
            string PassWord=this.TB_PassWord.Text.ToString();
            if (CommonUtility.Check_Login(UserName,PassWord))
            {
                Session["UserName"] = UserName;
                Response.Redirect("Main.aspx");
            }
            else
            {
                Response.Write("用户名或者密码错误");
            }    }还有,你的密码需要加密存放,这样可以保证传输安全,而且管理员都看不到密码
    做到这些就比较保险了