如何通过winform避免向表中输入重复值?

3

在我的项目中,我将客户端名称设置为主键,如果我输入相同的值,就会出现异常。现在我想要编写验证,即如果我重新输入主键值,则应该收到消息“数据已经存在”。请帮助我完成这个任务。我正在使用以下代码插入值:

      private void btnInsert_Click(object sender, EventArgs e)
       {
        if (txtName.Text == string.Empty)
        {
            MessageBox.Show("Please enter a value to Project Name!");
            txtName.Focus();
            return;
        }
        if (txtContactPerson.Text == string.Empty)
        {
            MessageBox.Show("Please enter a value to Description!");
            txtContactPerson.Focus();
            return;
        }
        SqlConnection con = Helper.getconnection();
        con.Open();
        string commandText = "InsertClient";
        SqlCommand cmd = new SqlCommand(commandText, con);
        cmd.Parameters.AddWithValue("@Name", txtName.Text);
        cmd.Parameters.AddWithValue("@ContactPerson", txtContactPerson.Text);
        cmd.CommandType = CommandType.StoredProcedure;
        MessageBox.Show("Client details are inserted successfully");
        txtName.Clear();
        txtContactPerson.Clear();
        object Name = cmd.ExecuteNonQuery();
        con.Close();
        BindData();            
    }

你收到的确切错误信息是什么? - user2749421
你的 InsertClient 程序没有传递任何 primary key,看起来 primary key 是自动增加的,比如使用 auto_increment?否则,在插入记录时实际的 primary key 是什么? - King King
ClientName 是主键。自动增量设置为另一个项客户 ID,它不是主键。 - karthik reddy
将一个按钮放在try catch块中并发布错误。 - Boy
4个回答

3
我倾向于允许用户尝试输入任何表面上有效的主键,如果出现重复,就会有一个异常可以捕获并显示给用户。
原因是您必须检查数据库中是否存在现有的键,因此最好通过尝试插入它并处理任何错误来完成此操作。
您可能可以改进验证和错误处理,弹出每个单独问题的消息框很烦人,最好有一个包含所有问题摘要的总结。同时,在显示消息框时保持数据库连接可能也不可取。
private void btnInsert_Click(object sender, EventArgs e)
   {
    if (txtName.Text == string.Empty)
    {
        MessageBox.Show("Please enter a value to Project Name!");
        txtName.Focus();
        return;
    }
    if (txtContactPerson.Text == string.Empty)
    {
        MessageBox.Show("Please enter a value to Description!");
        txtContactPerson.Focus();
        return;
    }
    SqlConnection con = Helper.getconnection();
    con.Open();
    string commandText = "InsertClient";
    SqlCommand cmd = new SqlCommand(commandText, con);
    cmd.Parameters.AddWithValue("@Name", txtName.Text);
    cmd.Parameters.AddWithValue("@ContactPerson", txtContactPerson.Text);
    cmd.CommandType = CommandType.StoredProcedure;

try
{
    object Name = cmd.ExecuteNonQuery();
    MessageBox.Show("Client details are inserted successfully");
    txtName.Clear();
    txtContactPerson.Clear();
    BindData();
}
catch(Exception ex)
{
        //Handle exception, Inform User
}
finally
{
        con.Close();
}      
}

1
我没有收到错误信息,但是在我输入重复值之后,首先我会得到MessageBox.Show("客户端详细信息已成功插入"); 然后是我在catch块中输入的“详细信息已存在”的消息。 - karthik reddy
消息框在插入之前已经显示了,应该在插入之后显示。如果您的存储过程没有吞噬它,尝试插入重复的主键将导致错误。 - user1450877

3

首先,您可以使用唯一索引或约束来防止表中发生重复。索引/约束可以与以下建议合作使用。如果您仅使用唯一索引而不使用下面的解决方案之一,则插入重复记录将抛出错误,您需要在另一端处理该错误。

您可以检查记录是否存在,并手动插入或更新:

create procedure MyProcedure
(
    @Name nvarchar(100),
    ...
)
as

    if not exists (select * from MyTable where Name = @Name)
    begin
        insert into MyTable (Name,...) values (@Name,...)
    end
    else
    begin
            update MyTable
            set ...
            where Name = @Name
    end

2

我理解您的要求,您想使用自己的代码代替异常。您可以通过使用try catch块来实现。请尝试以下代码:

try
{
    object Name = cmd.ExecuteNonQuery();
    MessageBox.Show("Client details are inserted successfully");
    txtName.Clear();
    txtContactPerson.Clear();
    BindData();
}
catch(Exception ex)
{
    //Handle exception, Inform User
}
finally
{
    con.Close();
}      

1

我倾向于使用Entity Framework,因为在这种情况下它会抛出一个异常。不过,我想你可以先运行一个 SQL 查询来检查它是否存在,尽管这可能会带来显著的性能开销。


很抱歉,无法从SQL服务器进行检查,通常客户没有访问数据库的权限,他只能在出现错误时知道它是主键。我的要求是,在进入插入按钮之前,客户应该在执行时间内仅获得验证或异常。 - karthik reddy
1
抱歉,我并不是指客户应该检查,我是指一个 sqlcmd 在主键上搜索表,然后您可以检查是否返回了任何行,如果是,则抛出自己的异常。(应该更清楚一些!:-)) - Steven Wood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接