如何从数据库中删除整行

How do I delete an entire row from a database

我如何从 sql 数据库中删除一行,无论是否使用存储过程,现在我已经尝试过不使用,使用按钮按下。 这是我到目前为止所拥有的,_memberid 是从数据库的不同形式发送过来的(对于上下文)。

private void btnDelete_Click(object sender, EventArgs e)
    {
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = Lib.SqlConnection;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "Delete * From Members where MemberId = " + _memberId;
        SqlDataAdapter adapter = new SqlDataAdapter();
        adapter.DeleteCommand = cmd;
        adapter.Fill(MembersDataTable); // Im fairly sure this is incorrect but i used it from old code
        DialogResult = DialogResult.OK;
    }

您可以使用 DataAdapter,但由于您没有使用数据表,所以不用这样更容易:

var sql = "DELETE FROM Members WHERE MemberId=@MemberId";
using(var cmd = new SqlCommand(sql, Lib.SqlConnection))
{
  cmd.Connection.Open();
  cmd.Parameters.Add("@MemberId",SqlDbType.Int).Value = _memberId;
  cmd.ExecuteNonQuery();
}

如果您使用的是 Dapper,您可以这样做:

Lib.SqlConnection.Execute("DELETE FROM Members WHERE MemberId=@MemberId", new {MemberId=_memberId});

如果您仍在使用 DataTables,我强烈建议您考虑使用它(或类似的东西)来简化您的数据库访问。它将使数据库上的 CRUD 逻辑变得轻而易举,并且你的代码将更易于维护,因为你可以摆脱所有奇怪的转换需求,boxing/unboxing,并减少运行时错误的机会,因为DataTables(列名)经常使用魔术字符串。一旦您开始使用 POCO 类,您将讨厌不得不使用 DataTables。也就是说,在某些地方 DataTables 是更好的解决方案(未知数据结构等),但这些地方通常很少见。

基本上我看到了三个主要的东西...

一个

您不需要查询中的 *DELETE 影响整行,因此无需指定列。所以就像:

DELETE FROM SomeTable WHERE SomeColumn = 123

两个

这里不需要SqlDataAdapter,只需要execute the query即可。例如:

cmd.ExecuteNonQuery();

"non query" 基本上是一个 SQL 命令,它不查询数据以获取结果。在此上下文中,插入、更新和删除通常是 "non queries"。 return 只是受影响的行数,如果需要,您可以使用它来仔细检查它是否符合您的预期。

三个

不要这样做:

cmd.CommandText = "Delete From Members where MemberId = " + _memberId;

这种字符串连接导致SQL注入。虽然从直觉上看,您正在使用 _memberId 作为查询值,但从技术上讲,您正在使用它 作为可执行代码 。它不太可能(虽然不是不可能)成为数值的问题,但它是字符串值的一个大问题,因为这意味着用户可以向您发送 任何字符串 而您将 按代码执行.

改为使用 query parameters。例如,您可以这样做:

cmd.CommandText = "Delete From Members where MemberId = @memberId";
cmd.Parameters.Add("@memberId", SqlDbType.Int);
cmd.Parameters["@memberId"].Value = _memberId;

这告诉数据库引擎本身该值是一个值而不是正在执行的查询的一部分,并且数据库引擎知道如何安全地处理值。

如果你想做一个简单的基于 ADO.Net 的删除,那么它会有点像他的:

private void DeleteById(int memberId)
{
   // or pull the connString from config somewhere
   const string connectionString = "[your connection string]";

   using (var connection = new SqlConnection(connectionString))
   {
       connection.Open();

       using (var command = new SqlCommand("DELETE FROM Members WHERE MemberId = @memberId", connection))
       {
           command.Parameters.AddWithValue("@memberId", memberId);
           command.ExecuteNonQuery();
       }
   }

使用参数防止SQL注入。