Как удалить данные из двух таблиц в одном запросе - PullRequest
0 голосов
/ 22 мая 2011

У меня есть две таблицы: 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;
        } 

Ответы [ 3 ]

2 голосов
/ 22 мая 2011

Возможно, я слишком упрощен, но вы, вероятно, можете просто сделать следующее: нет ничего плохого в том, чтобы включить несколько операторов 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;               
    } 

Определенно, лучше всего сначала удалить из таблицы Accounts перед AccountsUsers, потому что обычно таблица Accounts имеет внешнее ограничение для таблицы AccountsUsers. Это означает, что никакие строки не могут быть удалены в AccountsUsers до того, как соответствующая строка в Accounts будет удалена первой.

2 голосов
/ 22 мая 2011

В вашем коде есть небольшая логическая ошибка. Если во второй таблице есть одна запись, ExecuteNonQuery вернет 1, но если их больше, не вернет одну, а какой-то другой номер. Я бы изменил условное после второго удаления на:

if (sql_cmd.ExecuteNonQuery() > 1)

В связи с этим возникает вопрос: если во второй таблице нет записей, хотите ли вы, чтобы ваша функция возвращала false?

2 голосов
/ 22 мая 2011

Возможно, вам сначала нужно удалить учетные записи, но неясно, в каком именно направлении идет ваш внешний ключ.

Обычно вы не можете удалить из двух таблиц в одном запросе, но вы можете совершить транзакциюи иметь две инструкции DELETE в транзакции.

Вы также можете использовать каскадное ограничение удаления, чтобы удалять только из родительской таблицы (но я редко рекомендую это).

...