Удаление пользователя › нужно также удалить его проект, а затем действия для этого проекта?

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

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

Когда мой главный пользователь-администратор удаляет администратора, мне нужно, чтобы все проекты и действия (для их проектов) также были удалены. Мой сценарий удаления для пользователя пока прост и работает, но у меня возникли проблемы с тем, как получить идентификатор проекта, чтобы узнать, какие действия следует удалить (связанные с проектами, которые собираются удалить):

$userid = $_GET['userid'];

$query = "DELETE FROM users WHERE userid=".$userid;
$result = mysql_query($sql, $connection)
    or die("Error: ".mysql_error());

$query = "DELETE FROM projects WHERE userid=".$userid;
$result = mysql_query($sql, $connection)
    or die("Error: ".mysql_error());

$query = "DELETE FROM userprojects WHERE userid=".$userid;
$result = mysql_query($sql, $connection)
    or die("Error: ".mysql_error());


$query = "DELETE FROM activities WHERE projectid=".$projectid;
$result = mysql_query($sql, $connection)
    or die("Error: ".mysql_error());

Теперь первые три запроса выполняются нормально, очевидно, потому что идентификатор пользователя успешно извлекается. Однако 4-й и последний запрос, который я знаю, неверен, потому что нигде нельзя получить проект, однако я поместил его туда, чтобы помочь понять, что я пытаюсь получить!

Я предполагаю, что мне понадобится что-то вроде «WHERE projectid=», а затем что-то, чтобы собрать удаленные проекты из идентификатора пользователя, которые могут быть связаны с действиями для этого проекта (ов)! Это простая концепция, но у меня проблемы...


person Jamie    schedule 04.05.2010    source источник


Ответы (3)


Обязательно прочтите: Руководство по MySQL - FOREIGN КЛЮЧЕВЫЕ ограничения.

Обратите особое внимание на триггеры ON DELETE CASCADE, они сделают всю тяжелую работу за вас. знак равно

person Alix Axel    schedule 04.05.2010

Возможно, вы захотите взглянуть на многотабличный DELETE синтаксис. поддерживается MySQL:

$sql = "DELETE u, p, up, a 
        FROM users u
        LEFT OUTER JOIN projects p ON (u.userid = p.userid)
        LEFT OUTER JOIN userprojects up ON (u.userid = up.userid)
        LEFT OUTER JOIN activities a ON (p.projectid = a.projectid) 
        WHERE u.userid = {$userid}";

$result = mysql_query($sql, $connection)
    or die("Error: ".mysql_error());

Кроме того, пожалуйста будьте осторожны с защитой от рисков SQL Injection. Не используйте параметры веб-запроса без их фильтрации. По крайней мере, сделайте что-то вроде этого:

$userid = intval($_GET['userid']);
person Bill Karwin    schedule 04.05.2010

Если я правильно понял ваш вопрос, вы должны сначала изменить порядок своих запросов. Прежде чем удалять проекты, вы должны удалить действия для проектов для пользователя. Делая это в указанном порядке, вы теряете информацию, необходимую для последующего удаления.

Поэтому попробуйте их в этом порядке (я не использовал реальный синтаксис, чтобы было понятнее, что я делаю):

- delete from activities where projectid in (select projectid from projects where userid = $userid)
- delete from users...
- delete from projects...
- delete from userprojects...

Кроме того, по закону я обязан рекомендовать вам использовать переменные связывания вместо создания строк SQL на лету, как это. Похоже, вы сами заполняете эти строки, но такой код подвержен SQL-инъекциям, и вы, вероятно, этого не хотите.

person MJB    schedule 04.05.2010
comment
Спасибо, сейчас попробую - person Jamie; 04.05.2010
comment
Извините, я только что понял, что «выбрать идентификатор проекта из проектов, где идентификатор пользователя» не работает, потому что в таблице проектов нет идентификатора пользователя. userprojects содержит идентификатор проекта и идентификатор пользователя: S - person Jamie; 04.05.2010
comment
Но похоже, что идентификатор пользователя должен храниться где-то еще, как внешний ключ в другой таблице. Может быть, это двухэтапная проверка пользовательских проектов? Я не могу сказать, не видя структуры таблицы, но вы можете экстраполировать на основе этой логики, если это то, что вы хотите. - person MJB; 04.05.2010