如何在单个查询中从两个表中删除数据

Posted

技术标签:

【中文标题】如何在单个查询中从两个表中删除数据【英文标题】:How to Delete Data from Two tables in single query 【发布时间】:2011-05-22 01:00:26 【问题描述】:

我有两个表:Accounts,其中包含用户拥有的帐户信息,AccountUsers,其中包含在上述Accounts 表中拥有帐户的用户列表。

如果我必须删除一个用户,那么我必须从两个表中删除它们,其中AccountUsers 将拥有该用户的一行,而其他用户可能有很多,因为单个用户可以拥有多个帐户。

我编写了以下代码,它运行良好并从两个表中删除了行,但是每当第二个表中有多行时,它就无法删除它们并且ExecuteNonQuery() 返回 0,这意味着 0 行受到影响。

我想知道它是否可以在一行中完成。另外,如何对第二个表中的多行执行此操作,因为我现有的代码仅在有单行时才有效。

代码:

public static bool DeleteUser(int UserId)
        
            if (ConnectDatabase())
            
                sql_cmd = new SqlCommand();
                sql_cmd.Connection = sql_con;
                sql_cmd.Parameters.Add("@userId", SqlDbType.Int).Value = UserId;
                sql_cmd.CommandText = "DELETE FROM AccountsUsers WHERE Id = @userId";

                if (sql_cmd.ExecuteNonQuery() == 1)
                
                    sql_cmd = new SqlCommand();
                    sql_cmd.Connection = sql_con;
                    sql_cmd.Parameters.Add("@userId", SqlDbType.Int).Value = UserId;
                    sql_cmd.CommandText = "DELETE FROM Accounts WHERE userId = @userId";
                    if (sql_cmd.ExecuteNonQuery() == 1)
                    
                        return true;
                    
                    else
                        return false;

                
                else
                    return false;
            
            else
                return false;
         

【问题讨论】:

【参考方案1】:

您的代码中存在一些逻辑缺陷。如果第二个表中有一条记录,则 ExecuteNonQuery 将返回 1,但如果还有更多,它将返回一条,而是返回一些其他数字。我会将第二次删除后的条件更改为:

if (sql_cmd.ExecuteNonQuery() > 1)

这引发了一个问题 - 如果第二个表中没有记录,您是否希望您的函数返回 false?

【讨论】:

这是你所说的错误。实际上它在删除两行时返回 2 等等。我没想到,我以为只有 2 个值。0,1【参考方案2】:

您可能需要先删除帐户,但不清楚您的外键的确切方向。

您通常不能在一个查询中从两个表中删除,但您可以创建一个事务并在该事务中拥有两个 DELETE 语句。

您还可以使用级联删除约束,以便仅从父表中删除(但我很少推荐这样做)。

【讨论】:

mysql 中可以。 DELETE FROM AccountsUsers, Accounts USING AccountsUsers INNER JOIN Accounts WHERE AccountsUsers.Id = Accounts.userId AND AccountsUsers.Id = @userId Accountstable 中有一个名为 Id 的主键,但我使用的是 userId 列,它是我在数据库表中插入值时填充的列。【参考方案3】:

我可能太简单了,但您可能只需执行以下操作 - 在一个以分号分隔的命令中包含多个 sql 语句并没有错:

    static bool DeleteUser(int UserId)
    
        if (ConnectDatabase())
        
            sql_cmd = new SqlCommand();
            sql_cmd.Connection = sql_con;
            sql_cmd.Parameters.Add("@userId", SqlDbType.Int).Value = UserId;
            sql_cmd.CommandText = "DELETE FROM Accounts WHERE userId = @userId;DELETE FROM AccountsUsers WHERE Id = @userId;";

            if (sql_cmd.ExecuteNonQuery() == 1)
            
                return true;
            
            else
                return false;               
     

在 AccountsUsers 之前先从 Accounts 表中删除绝对是最佳实践,因为通常 Accounts 表会对 AccountsUsers 表有一个外部约束。这意味着在 Accounts 中的相应行首先被删除之前,AccountsUsers 中的任何行都不能被删除。

【讨论】:

是的,但我不明白问题是Steve Mallory告诉是什么

以上是关于如何在单个查询中从两个表中删除数据的主要内容,如果未能解决你的问题,请参考以下文章

在单个查询中从 mongo 中删除多个文档

查询及删除重复记录

从同一查询中的两个表中删除 NULL 行[重复]

在一个灵活的查询中从多个表中删除行

在Oracle中从表中删除重复行

Android KInvey 如何在单个查询中从多个集合中查询详细信息