Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# System.Data.dll c中发生类型为“System.Data.OleDb.OLEDBEException”的未处理异常_C#_Database_Winforms_Ms Access_Datagridview - Fatal编程技术网

C# System.Data.dll c中发生类型为“System.Data.OleDb.OLEDBEException”的未处理异常

C# System.Data.dll c中发生类型为“System.Data.OleDb.OLEDBEException”的未处理异常,c#,database,winforms,ms-access,datagridview,C#,Database,Winforms,Ms Access,Datagridview,我已经创建了windows窗体,其功能是将信息添加到数据库中。但是,我有个问题。当我在Product Code(产品代码)列中键入类似于SM0001的数字,然后按enter键时,它会将数据存储到数据库中;当我键入与以前键入的数字相同的数字时,它不会阻止数据库中已存在类似于输入的产品代码的用户。因此,这是我当前在系统中datagridview中显示的数据库: 如您所见,第1行和第2行具有相同的产品代码。。我的问题是:如何防止用户两次输入相同的数字 我已经将数据库中的主键更改为产品代码,但下面是我得

我已经创建了windows窗体,其功能是将信息添加到数据库中。但是,我有个问题。当我在Product Code(产品代码)列中键入类似于SM0001的数字,然后按enter键时,它会将数据存储到数据库中;当我键入与以前键入的数字相同的数字时,它不会阻止数据库中已存在类似于输入的产品代码的用户。因此,这是我当前在系统中datagridview中显示的数据库:

如您所见,第1行和第2行具有相同的产品代码。。我的问题是:如何防止用户两次输入相同的数字

我已经将数据库中的主键更改为产品代码,但下面是我得到的错误:

错误是:

An unhandled exception of type 'System.Data.OleDb.OleDbException' occurred in System.Data.dll

Additional information: The changes you requested to the table were not successful because they would create duplicate values in the index, primary key, or relationship. Change the data in the field or fields that contain duplicate data, remove the index, or redefine the index to permit duplicate entries and try again.
错误发生在:

cmd.ExecuteNonQuery

关于此功能:

private void AddDatabase(object sender, EventArgs e)
        {
            using (OleDbConnection conn = new OleDbConnection(connectionString))
            {
                string query = "INSERT INTO [Table] ([ProductCode], [Description], [Price]) VALUES (@ProductCode, @Description, @Price)";
                conn.Open();
                using (OleDbCommand cmd = new OleDbCommand(query, conn))
                {
                    cmd.Parameters.Add("@ProductCode", System.Data.OleDb.OleDbType.VarChar);
                    cmd.Parameters["@ProductCode"].Value = this.numericTextBox1.Text;
                    cmd.Parameters.Add("@Description", System.Data.OleDb.OleDbType.VarChar);
                    cmd.Parameters["@Description"].Value = this.textBox3.Text;
                    cmd.Parameters.Add("@Price", System.Data.OleDb.OleDbType.Integer);
                    cmd.Parameters["@Price"].Value = this.textBox4.Text;
                    cmd.ExecuteNonQuery(); // The error is here
                    if (_choice.comboBox1.Text == "English")
                    {
                        System.Media.SoundPlayer _sound = new System.Media.SoundPlayer(@"C:\Windows\Media\Windows Exclamation.wav");
                        _sound.Play();
                        DialogResult _dialogResult = MessageBox.Show("Added Successfully!", "Success", MessageBoxButtons.OK);
                        if (_dialogResult == DialogResult.OK)
                        {
                            ViewDatabase(sender, e);
                            ClearTextBoxes(sender, e);
                        }
                    }
                }
                conn.Close();
            }
        }
我希望当用户键入相同的产品代码时,messagebox会显示不允许键入的产品代码,因为它存在于数据库中,并且不会给出错误消息,从而终止程序的运行

我怎么修理它

多谢各位


非常感谢您的回答

您遇到的错误很正常。不能在主键中插入重复项,也不能包含“NULL”列。有关主键的详细信息:

在执行AddDatabase之前,您应该检查该密钥是否已存在于数据库中。你可以用很多不同的方法来做这件事

在数据库上执行select

SELECT TOP 1 ProductCode FROM Table WHERE ProductCode = 'this.numericTextBox1.Text'"
如果此查询生成结果,则productcode已存在于数据库中,不应执行该查询

检查datagridview的数据源

作为datagridview的数据源,您可能提供了一个列表/数据集。您可以检查列表中是否存在新输入的ProductCode。您可以在这里使用链接,也可以只是迭代源代码。让你的船漂浮的东西

如果您能告诉我数据源的类型,那么我可以提供一个代码示例

检查您的Datagridview

如果datagridview包含数据库的所有记录,则可以迭代行并检查第一列是否包含与新输入的产品代码相同的productcode

在一行行中的某物

 foreach (DataGridViewRow row in dgvDataGridView.Rows)
      {
      if(row.Cells[0].Value.toString().equals(this.numericTextBox1.Text))

           { 

           // Productcode is already present
           // Throw message/exception Or whatever
           break; 
           }
      }
我会选择选项1,因为在执行INSERT之前,datagridview/datasource可能不会显示/保留表中的所有记录。您可以检查数据库是否已经包含ProductCode,该ProductCode似乎是表中的一个键

类似于从我的一个项目中复制/粘贴代码,但应该是清晰的

 var command = new OleDbCommand("SELECT COUNT(*) FROM results WHERE id = ?", _connection);
 command.Parameters.Add("id", OleDbType.Date).Value = id;
 if ((int)command.ExecuteScalar() == 0)
 {
     // not exists
 }
建议:不要将AddDatabase设置为事件处理程序,而是创建一个单独的类来处理数据库操作,将方法AddDatabase设置在那里并从事件处理程序调用它

您可以有2个方法,然后Existsid和Add…,因此在事件中可以执行简单的重复检查:

if(Database.Exists(id))
{
    // show errror
    return;
}
DataBase.Add(...);
如果你的错误是 system.data.dll中发生类型为“system.data.oledb.OLEDBEException”的未处理异常。其他信息:溢出 对于音符或数字,以DB为单位的字符很少 请将cloumn格式更改为更大 数字-->整数上限为双精度
Tanks

我想你使用数据集/列表作为数据源?有很多方法可以解决你的问题,但你的问题的直接答案是try/catch/finally块。然后您可以处理数据库代码、带有键/约束的本地数据表等。非常感谢先生!没问题!玩得高兴: