2013-03-18 71 views
0

我想從mySQL表中使用php的PDO對象刪除匹配一對條件的所有行。我想不通爲什麼它不工作:無法從循環中的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表,idpidcid,我想刪除這些比賽正在呼應。

+0

所以,你的問題與mysqli無關,但只是基本的PHP語法(和不正確的使用$ this關鍵字) 。另一個本地化的問題污染了該網站 – 2013-03-18 11:01:48

+0

只是'var_dump()'查詢,查找雙引號或單引號,因爲有時候它們不存在或只是'var_dump()'查詢和去phpmyadmin並將查詢粘貼到查詢選項卡中,它將顯示你有什麼樣的錯誤,同時'DELETE FROM table_name WHERE id = 1'已經通過表中的所有記錄循環顯示 – 2013-03-18 10:39:25

+0

顯然我不知道這個問題是什麼,我在循環中使用PDO/mySQL時遇到了問題,因爲外面的代碼幾乎完全相同並且正在工作。但是,我會考慮下次使用Code Review或其他網站,謝謝您的意見。 – Alex 2013-03-19 12:13:41

回答

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 2013-03-18 10:37:09

2

所以解決這個問題的更好的辦法是使用準備好的語句,並得到變量從查詢了。這樣一來,你倆解決這個問題以及修復安全問題(SQL注入),你現在所擁有的......

,這裏是你的代碼轉換成有效的預處理語句:

$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 2013-03-18 15:11:43