在更新记录时,如何在数据库中防止重复记录



在我的mysql表中,我看起来像这个

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

现在,我在C#中进行了一个用户控件,其中允许用户更新所有列,除了主要的" ControlNum"。因此,假设每列在上述用户控件中都有自己的文本框,以免在标题列中重复,例如用户编辑第2行标题并将其放置为"火影忍者",也将被重复。此方法称为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和描述的数量,并且不打算真正更新标题,我的方法仍然检测到有重复的内容,因为我的逻辑是"如果我的逻辑是"(ctr == 1)" ..我想我错过了某种方法,或者我在这里使用错误的方法。>

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

最简单的方法是按照Mbeckish的建议,对标题列创建独特的约束:

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();
    }
}

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

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

然后您的逻辑还应检查控制num是否有差异

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,该尺度仅返回第一行的第一列(在这种情况下为1)而无需构建mySqlDatareAder对象

更改副本查找SQL:

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

如果计数> 1,则有一个重复。

最新更新