更新记录时如何防止数据库中出现重复记录?

How do i prevent duplicate records in my database while updating records?

在我的 mysql table 中我做了这个样子

ControlNum|Title  |NumOfEpis|Description|
001       |naruto |500      |some text  |
002       |conan  |700      |some text  |

现在我在 C# 中创建了一个用户控件,允许用户更新除主列之外的所有列"ControlNum"。因此,假设每一列在该用户控件中都有自己的文本框,因此为了避免标题列中的重复,例如,如果用户编辑第 2 行标题并将其放入 "naruto",它也会被重复..所以我创建了这个名为 checkData() 的方法;

void checkData()
    {
        SuspendLayout();
        try
        {
            MySqlConnection conn = new MySqlConnection(myConnection);
            conn.Open();
            MySqlCommand command = new MySqlCommand("SELECT * FROM maindatabase.animelist where TitleAnime=?Title;", conn);
            //command.Parameters.AddWithValue("?CN", int.Parse(a.ToString()));
            command.Parameters.AddWithValue("?Title", textBox3.Text);
            MySqlDataReader reader = command.ExecuteReader();

            int ctr = 0;
            while (reader.Read())
            {
                ctr++;

            }
            if (ctr == 1)
            {
                my = Form.ActiveForm as MyList;
                my.msg = new Message_Box();
                my.msg.Descrip.Text = "Record is already in the Database";
                my.msg.Title.Text = "Duplicate Record";
                my.msg.ShowDialog();
            }
            else
            {

                updateData();
            }


            conn.Close();
            ResumeLayout();
        }
        catch (Exception ex)
        {
            MessageBox.Show("" + ex);
        }
    }


它工作正常,但我的问题是,如果用户只更新 epis 和描述的数量而不真正打算更新标题,我的方法仍然检测到有重复项,因为我逻辑是"if(ctr == 1)"..我想我错过了一些方法或者我在这里采用了错误的方法..所以我希望有人能启发我..很抱歉在这里成为菜鸟Y.Y

更改重复结果 SQL :

SELECT MAX(Title) as Count
FROM maindatabase.animelist
GROUP BY Title  , NumOfEpis, Description

如果 Count > 1 ,则存在重复。

您不希望有两个内容相同的标题。这可以通过该列上的 UNIQUE 索引自动实现。但是,如果您不想为此添加索引,则可以将查询更改为

SELECT ControlNum FROM maindatabase.animelist 
WHERE TitleAnime=?Title;

那么您的逻辑还应该检查 ControlNum 的差异

int currentNum = int.Parse(a.ToString()));
while (reader.Read())
{
    int ctrlNum = reader.GetInt32(0);
    if(ctrlNum != currentNum)
        ctr++;

}
if (ctr > 0)
    ......

通过这种方式,只有当检索到的 ControlNum 与您在界面中选择的不同时,您才增加计数器

另一种方法如下(请参阅@mbeckish 下面的评论)

SELECT 1 FROM maindatabase.animelist 
WHERE TitleAnime=?Title AND ControlNum <> ?CN

command.Parameters.AddWithValue("?CN", int.Parse(a.ToString()));
command.Parameters.AddWithValue("?Title", textBox3.Text);
object result = command.ExecuteScalar();
if(result != null)
{
    // Found a record with different ControlNum but with the same title
    // Error here
}

这可能比第一个更好,因为您不需要循环并且可以使用更简单且性能更高的 ExecuteScalar returns 仅第一行的第一列(在本例中为 1 ) 而无需构建 MySqlDataReader object

如果您的应用程序支持多个用户,您需要确保在检查重复项和数据库更新之间没有其他用户进行更改。

最简单的方法是按照 mbeckish 的建议,在标题列上创建一个 UNIQUE 约束:

ALTER TABLE maindatabase.animelist 
ADD CONSTRAINT U_animelist_TitleAnime UNIQUE (TitleAnime)

然后数据库引擎将强制执行唯一标题,您的客户端可以通过捕获任何违反约束的异常来处理用户反馈:

void checkData()
{
    SuspendLayout();
    try
    {

        updateData();

    }
    catch (Exception ex)
    {
        MySqlException sqlEx = ex as MySqlExecption;
        // If there is a constraint violation error.
        // (I may have the wrong error number, please test.)
        if (sqlEx != null && sqlEx.Number == 1062) 
        {
            my = Form.ActiveForm as MyList;
            my.msg = new Message_Box();
            my.msg.Descrip.Text = "Record is already in the Database";
            my.msg.Title.Text = "Duplicate Record";
            my.msg.ShowDialog();
        } 
        else 
        {
            MessageBox.Show("" + ex);
        }
    }
    finally
    {
        ResumeLayout();
    }
}