如何根据行号在表中删除
本文关键字:删除 何根 | 更新日期: 2023-09-27 18:26:00
我的情况是,我有一个包含一些数据的表,其中也有主键ID,我在datagridview中显示这些数据,现在我必须删除datagridview和表中的任何特定行。
现在点击部分的代码是可以的,我得到了行号,我删除了表中主键ID对应的行,但当删除一行时会发生探测,然后我点击了第三行,然后转到表中,试图找到ID(PK),它是3,然后删除它,但这不是一个好方法,因为现在表格的顺序将是
1
2 //3 is deleted
4
5
因此,下次当我在数据网格视图中单击4时,它将查找ID=3(因为行号是3),因此不会删除任何内容,因为我的表中现在有ID=3。
所以我正在寻找一种基于行号而不是ID号进行删除的方法,这样我在数据网格视图中单击哪一行,表中相应的行号也会被删除。
我根据ID删除行的代码是:
internal void DeleteIndividualParcel(string tableName, string Conx, int number)
{
//number is the row number clicked in dataGridView
NpgsqlConnection MyCnx = new NpgsqlConnection(Conx);
NpgsqlCommand MyCmd;
List<string> finalList = new List<string>();
string delete = "";
delete = "DELETE FROM " + tableName + " WHERE id =" + number + ";";
try
{
MyCnx.Open();
}
catch (Exception ex)
{
MessageBox.Show("The connection can't be opened!" + ex.Message);
}
MyCmd = new NpgsqlCommand(delete, MyCnx);
try
{
MyCmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("The query can't be executed from DeleteParcel!" + ex.Message);
}
MyCnx.Close();
}
如何更改代码以删除行号?
请不要使用此解决方案。相反,请遵循其他答案中的建议:在任何CRUD操作中始终保留主键,因此您可以删除where id=something。
您应该始终根据可靠的标准进行删除,而不是根据行在表中的位置进行删除(除非您只是在清理表的一部分,否则row_number()业务非常方便)。为什么?你可以删除一些你不打算的东西,当:
- 在您加载数据之后,在您想要删除记录之前,有人会修改表,因此UI和DB中的行号不匹配
- 如果您有一个可排序的表,那么传递排序标准要困难得多,而不仅仅是一个键值(ID)
- 解决方案太难看了
现在,既然这显然是PostgreSql,这就是您需要的:
DO $$
DECLARE vid INT;
BEGIN
SELECT tt.id into vid
from (select id, row_number() over () as rn from testtable) tt
WHERE tt.rn=2;
DELETE FROM testtable WHERE testtable.id=vid;
END $$;
删除第三行
由于第三行根据您对表的排序方式而有所不同,如果组成该DataGrid的查询具有Order By
,请确保将其包含在over()
中,如下所示:
row_number() over(ORDER BY id) as rn
处理此问题的最快、最简单、最糟糕的方法是在每次删除后重新查询数据库并重建网格。
一个不那么脏但也更困难的方法是,当您从网格中删除该项时,将其从列表中删除。
另一种方法是将ID放在网格中的隐藏列中。
基本规则:
首先,在UI和数据库表之间进行双向通信时,应该小心选择表中可以唯一定义记录集的正确列。因此,一般选择"PK"(主键)列。
其次,在进行任何类型的CRUD(创建、读取、更新和删除)操作时,双方的列表都应该相应地更新。
如果使用行号作为键来操作数据库记录,请确保每次操作后UI和DB中的列表都同步。