首页 > 解决方案 > 在 foreach 循环中以编程方式擦除 SQL 中的一行?

问题描述

我有一个使用 PostgreSQL 的关系数据库连接meal_ingredientsingredient营养价值(有关更多信息,请参见此处)。在 WinForms 应用程序中,有一个按钮从 DataGridView 中获取值,然后将每一行放入一个数组中。

DataGridView 中的每一行都是具有营养价值的成分。在 DataGridView 上方,一个文本框接受一个字符串作为餐点名称。单击按钮(下面的代码)后,数组值会执行以下两项操作之一:

在我的代码中,正如您所见,一旦将数据放入数组中,就会与数据库建立连接,并将SELECT查询结果加载到 DataTable 中。

meal_name如果字段与文本框中的字符串值匹配,则随后的循环将触发 MessageBox 。这工作正常。

我的问题如下。无论 DataGridView 中存在多少行,MessageBox 都会触发多次;例如,如果有两行,我将看到两个 MessageBox。这本身不是问题,除非用DELETEandINSERT语句替换此 MessageBox 会引发错误。

代替MessageBox.Show("test");,我将放置一条 SQL 语句来删除任何记录 where meal_name == txtMealName.Text,然后放置第二条 SQL 语句来插入基于 DataGridView 行的新记录。当然,如果 MessageBox 根据行数触发,我预计 SQL 也会出现那么多次。同样,原则上这很好。但我只是想知道这是否会导致任何类型的冲突(例如,SQL 抛出异常,因为没有剩余的行要删除)?

 private void btnMealAdd_Click(object sender, EventArgs e)
    {
        if (txtMealName.Text != "")
        {
            foreach (DataGridViewRow row in dgvMealIngredient.Rows)
            {
                List<string> macroList = new List<string>();
                macroList.Add(row.Cells[0].Value.ToString());
                macroList.Add(row.Cells[9].Value.ToString());

                macroList.Add(txtMealName.Text);

                String[] str = macroList.ToArray();

                NpgsqlConnection conn = new NpgsqlConnection(Globals.connectionString());
                conn.Open();
                NpgsqlCommand comm = new NpgsqlCommand();
                comm.Connection = conn;
                comm.CommandType = CommandType.Text;
                comm.CommandText = "SELECT * FROM meal_ingredients";
                NpgsqlDataReader dr = comm.ExecuteReader();
                DataTable dt = new DataTable();
                dt.Load(dr);

                foreach (DataRow dataRow in dt.Rows)
                {
                    if (dataRow[0].ToString() == txtMealName.Text)
                    {
                        MessageBox.Show("test");
                    }
                    Debug.WriteLine(dataRow[0]);
                }                    
            }         
        }
        else
        {
            MessageBox.Show("error: enter a meal name");
        }
        
    }

数据库关系的简化形式(注意 qty 是 DataGridView 中的字段之一):

db 关系图

标签: c#postgresql

解决方案


只是用 INSERT 或 DELETE 替换它会引发错误

SQL DELETE 通常可以运行多次而不会出错。它要么删除一些行,要么不删除,但如果另一个表中有依赖记录并且没有安排以级联方式删除或断开它们,它通常只会导致错误。DELETE 语句影响 0 行不是错误

当一个或多个列上存在唯一约束时,SQL INSERT 通常只能在随后(第一次运行之后)没有被禁止时运行多次。由于您设计的大多数表实际上都应该有一个主键,因此您只能为键列插入具有唯一值的行。如果您没有将值的生成移交给数据库,那么重新运行相同的 INSERT 将在第二次运行时失败。如果该表依赖于另一个表具有相关行并且外键约束支持这一点,则与父表中的行不相关的插入将在第一次运行时失败


推荐阅读