2013-03-18 2 views
0

Я пытаюсь удалить все строки, соответствующие двум условиям из таблицы mySQL, используя PDO-объект php. Я не могу понять, почему он не работает:Невозможно удалить несколько строк из таблицы MySQL в цикле

//This deletes all comments for a given post; 
//Querying database for existent comments on that post; 
$this->query = $this->db->query(
"SELECT cid 
FROM comments 
WHERE id = '$html_data->id' AND pid = '$html_data->pid'" 
); 
//Fetching results into an array; 
$this->rows = $this->query->fetchAll(PDO::FETCH_ASSOC); 
//Deleting each comment on that post; 
foreach ($this->rows as $this->row) { 
    $this->db->exec(
    "DELETE from comments 
    WHERE cid = '$this->row['cid']'" 
    ); 
}; 
//Deleting the post itself; 
$this->db->exec(
"DELETE from posts 
WHERE id = '$html_data->id' AND pid = '$html_data->pid'" 
); 

//Deleting the post itself работы, но часть внутри цикла foreach не по какой-то причине. Для отладки я добавил следующее внутри цикла:

echo "WHERE cid = '{$this->row['cid']}'"; 

И он вернулся так же, как ожидалось:

WHERE cid = '1' 
WHERE cid = '2' 

Таким образом, данные которые извлекаются не проблема. Я также попытался

WHERE id = '$html_data->id' AND pid = '$html_data->pid' AND cid = '$this->row['cid']'" 

Вместо того, чтобы использовать только cid, и это также не работает. Повторяя это возвращается, как и ожидалось:

WHERE id = '1' AND pid = '1' AND cid = '1' 
WHERE id = '1' AND pid = '1' AND cid = '2' 

И да, я проверил comments стол, id, pid и cid, что я хочу, чтобы удалить матчи те, которые в настоящее время эхом.

+0

Итак, ваша проблема не имеет ничего общего с mysqli, но только с базовым синтаксисом PHP (и неправильным использованием этого ключевого слова $) , Еще один слишком локализованный вопрос о загрязнении сайта –

+0

Просто 'var_dump()' запрос, искать двойные кавычки или одинарные кавычки, потому что бывают случаи, когда они отсутствуют или просто 'var_dump()' запрос, и переход на phpmyadmin и вставьте запрос на вкладку запроса, он покажет, какие ошибки у вас есть, также 'DELETE FROM table_name WHERE id = 1' уже пробивает все записи в таблице –

+0

Очевидно, что я не знал, в чем проблема, для мне было проблемой с использованием PDO/mySQL внутри цикла, поскольку код снаружи был почти идентичным и работал.Но в следующий раз я рассмотрю возможность использования Code Review или другого веб-сайта, спасибо за ваш вклад. – Alex

ответ

0

Это должно быть

$this->db->exec(
"DELETE from comments 
WHERE cid = '$this->row[cid]'" 
); 

ИЛИ вы можете также использовать

$this->db->exec(
"DELETE from comments 
WHERE cid = '{$this->row['cid']}'" 
); 
+1

Ваш второй подход работал, спасибо. Это странно, так как запрос ниже '// Удаление самого сообщения работает очень хорошо, и мне не нужно использовать {}. – Alex

2

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

Вот ваш код преобразуется в эффективные подготовленные заявления:

$stmt= $this->db->prepare(
    "SELECT cid 
    FROM comments 
    WHERE id = ? AND pid = ?" 
); 
$this->query = $stmt->execute(array($html_data->id, $html_data->pid)); 

$this->rows = $this->query->fetchAll(PDO::FETCH_ASSOC); 

$deleteStmt = $this->db->prepare(
    "DELETE from comments 
    WHERE cid = ?" 
); 
foreach ($this->rows as $row) { 
    $deleteStmt->execute(array($row['cid'])); 
}; 

//Deleting the post itself; 
$stmt = $this->db->prepare(
    "DELETE FROM posts 
    WHERE id = ? AND pid = ?" 
); 
$stmt->execute(array($html_data->id, $html_data->pid)); 

Однако, вы можете очистите его еще больше. Лучший способ справиться с этим - использовать внешние ключи. Например, давайте создадим внешний ключ из нашей таблицы комментариев pid на посты id.

CREATE TABLE posts (
    id INT, 
    name VARCHAR(35), 
    PRIMARY KEY (`id`) 
) ENGINE = InnoDB; 

CREATE TABLE comments (
    id INT, 
    pid INT, 
    name VARCHAR(35), 
    PRIMARY KEY (`id`), 
    CONSTRAINT `posts_id` 
    FOREIGN KEY `posts_id` (`pid`) 
    REFERENCES `posts` (`id`) 
    ON DELETE CASCADE 
    ON UPDATE CASCADE 
) ENGINE = InnoDB 

Прелесть в том, что ваш большой блок кода там сводится именно к этому:

$stmt = $this->db->prepare(
    "DELETE FROM posts 
    WHERE id = ? AND pid = ?" 
); 
$stmt->execute(array($html_data->id, $html_data->pid)); 

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

+0

Я окончательно взглянул бы на это, спасибо. – Alex

Смежные вопросы