PHP准备语句在foreach中插入太多

时间:2014-12-28 04:03:16

标签: php loops mysqli foreach prepared-statement

在我输入的文字中我只是输入

  

biografi,

它应该只插入1行,

但它插入了5次(可能来自此 - >我的类别表包含5个类别)

如果我输入

  

bigrafi,字典,

其插入10次

$categories = explode(",", $kategori);
    $stmt2 = $mysqli->prepare("INSERT INTO book_category (idbook, idcategory)
                                    SELECT book.idbook, category.idcategory
                                    FROM book, category
                                    WHERE book.isbn = ?
                                    AND category.nmcategory = ?");
    foreach ($categories as $category) {
        if (empty($category) || $category == "") {
            continue;
        }

        $stmt2->bind_param("si", $isbn, $category);
        if($stmt2->execute()) {

        } else {
            showAlert("Error when insert category");
        }
    }
    $stmt2->close();

它应该只将biografi(3)id插入book_category表

idbook | idcategory
    8 | 3

但插入5次

idbook | idcategory
    8 | 1
    8 | 2
    8 | 3
    8 | 4
    8 | 5

enter image description here

抱歉不好解释,我不会说英语。 我希望你明白我的意思

SELECT idcategory,nmcategory FROM category

| idcategory | nmcategory |
| 1          | kamus      |
| 2          | agama      |
| 3          | biografi   |
| 4          | novel      |
| 5          | komik      |

SELECT idbook,isbn FROM book

| idbook | isbn |
| 1      | 111  |

1 个答案:

答案 0 :(得分:3)

您将从两个表中返回两条独立的信息 - 请求的isbn和请求的category无关(您通过插入创建他们的关系book_category),因此在没有加入条件的情况下进行连接查询会产生笛卡尔积(所有书籍都乘以所有类别)。由于categories表中总共有5行,因此返回所有5行。

您可以使用两个子选项构建查询 - 一个查询book,另一个查询category。每个子选择将只返回一个值,这两个将合并为一行。

// The query reduces to "(SELECT book), (SELECT category)" as separate
// actions, which can be done together as subselects
$stmt2 = $mysqli->prepare("INSERT INTO book_category (idbook, idcategory)
    SELECT
     (SELECT idbook FROM book WHERE isbn = ?) AS idbook,
     (SELECT idcategory FROM category WHERE nmcategory = ?) AS idcategory");

// Your bind/execute/fetch can remain the same
foreach ($categories as $category) {
    if (empty($category)) {
        continue;
    }

    $stmt2->bind_param("si", $isbn, $category);
    if($stmt2->execute()) {

    } else {
        showAlert("Error when insert category");
    }
}
$stmt2->close();