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

时间:2011-05-22 01:00:27

标签: c# sql query-optimization

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

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

我编写了以下代码,该代码运行良好并从两个表中删除了行,但只要第二个表中有多行,就无法删除它们,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;
        } 

3 个答案:

答案 0 :(得分:2)

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

您通常不能从单个查询中的两个表中删除,但您可以在事务中创建事务并使用两个DELETE语句。

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

答案 1 :(得分:2)

我可能过于简单了,但您可能只是执行以下操作 - 在由分号分隔的单个命令中包含多个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表上具有外部约束。这意味着在首先删除帐户中的相应行之前,不会在AccountsUsers中删除任何行。

答案 2 :(得分:2)

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

if (sql_cmd.ExecuteNonQuery() > 1)

提出了一个问题 - 如果第二个表中没有记录,你希望你的函数返回false吗?