【问题标题】:OleDbException Unhandled: No value given for one or more parametersOleDbException 未处理:没有为一个或多个参数指定值
【发布时间】:2013-01-20 05:02:56
【问题描述】:

之前尝试使用用户名和密码创建登录页面。 但是,由于我的用户表有 3 个角色,我想创建一个登录页面,根据用户的角色授予用户登录权限。

例如:管理员到管理页面,员工到员工页面等。

在尝试实现这一点时,我的一行中遇到了以下错误: OleDbException 未处理,没有为一个或多个参数指定值。

这是我的登录代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;

namespace AcuSapp
{
    public partial class Login : Form
    {
        OleDbConnection LoginLink = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\SB18\\Documents\\Visual Studio 2010\\Projects\\AcuSapp\\AcuSapp\\bin\\debug\\AcuzioSecureStore DatabaseX.accdb");
        public Login()
        {
            InitializeComponent();
            //textBox_username.Text = "LittleJohn";
            //textBox_password.Text = "HelloJohn";
        }


        private void button_login_Click(object sender, EventArgs e)
        {
             string username = textBox_username.Text;
            string password = textBox_password.Text;
            string role_name = comboBox_role.Text;

            //this is to give notification if username and password is lesser than 4 characters
            // .length will count the characters in the string
            // This is to reduce redundant calls. Less calls = less taxing on the db
            if ((username.Length < 4) || (password.Length < 4))
            {
                MessageBox.Show("Wrong Credentials!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                // Set authentication as false. By default, user is not authenticated yet.
                bool isAuthenticated = false;
                //Opens the connection to db
                LoginLink.Open();
                // Sets the SQL command to be executed
                // Since it is a variable command, it becomes a new SQL command to be executed in Microsoft access
                // + is to join the string together
                //Does string comparing to see if username and password match exactly, case sensitive.

                //var cmd = new OleDbCommand("SELECT COUNT(*) FROM [User] WHERE username = '" + username + "' AND password = '" + password + "' ", LoginLink);
                var cmd = new OleDbCommand("SELECT COUNT(*) FROM [User] WHERE STRCOMP(username, '" + username + "', 0) = 0 AND STRCOMP(password, '" + password + "', 0) = 0 AND STRCOMP(role_name, '" + role_name + "', 0) = 0", LoginLink);
                // (int)cmd.ExecuteScalar only reads the first few rows from the db
                isAuthenticated = (int)cmd.ExecuteScalar() == 1; //Error on this line.
                //Closes connection to db
                LoginLink.Close();
                // if isAuthenticated is true
                if (isAuthenticated)
                {
                    // This will open the next page which is form1
                    Client hello = new Client(this);
                    hello.Show();
                    // Hides the login form
                    this.Hide();
                }
                else
                {
                    //Always remember to put the last statement in curly braces
                    //otherwise it wont show the previous error will show this messsage instead
                    MessageBox.Show("Wrong Credentials!");
                }
            }


        }
    }
}

【问题讨论】:

  • 这里有很多问题。首先,您很容易受到 SQL 注入攻击。其次,如果您的用户拥有多个角色会怎样? (发生的事情比您想象的要多。)创建一个存储过程来验证您的用户名/密码,或者至少参数化您的输入。然后,使用链接表将您的角色与用户分开。

标签: c#


【解决方案1】:

您的连接字符串看起来有点不对劲。您定义了两个数据源,其中一个被分配了一个不是有效数据源的提供程序:

"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\SB18\\Documents\\Visual Studio 2010\\Projects\\AcuSapp\\AcuSapp\\bin\\debug\\AcuzioSecureStore DatabaseX.accdb"

您应该删除该部分:

Data Source=Provider=Microsoft.ACE.OLEDB.12.0;

尝试下面的连接字符串可能会有所帮助。

 OleDbConnection LoginLink = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\SB18\\Documents\\Visual Studio 2010\\Projects\\AcuSapp\\AcuSapp\\bin\\debug\\AcuzioSecureStore DatabaseX.accdb");

【讨论】:

  • 啊,我想我明白了。 "AND STRCOMP(role_name, '" + role_name + "', 0) = 0", LoginLink); // (int)cmd.ExecuteScalar 只从数据库中读取前几行"
  • 既然我在使用组合框,我应该从这里做什么?
  • Well ExecuteScalar 从数据库中读取第一列的第一行,正如微软在此处描述的那样...msdn.microsoft.com/en-us/library/… 如果您只是返回 1 或 0,这没关系。至于您的组合框问题,您可能想要这样做: string role_name = comboBox_role.SelectedValue 这将为您提供用户选择的项目。
  • 无法编辑我的最后一条评论,所以我要添加另一个评论。 comboBox_role.SelectedValue 将为您提供用户选择的“VALUE”。如果您需要选定的文本,您可以使用 comboBox_role.SelectedText
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 2011-01-23
  • 1970-01-01
  • 2017-12-25
  • 2015-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多