我的数据库 (MySQL/InnoDB) 中有三个表:pupil
、evening_activity
和 pupil_evening_activity
。您可以猜到,pupil
和 evening_activity
之间存在 m:m
关系。
我有一个 HTML 表单,用于插入新学生并将晚间事件与他们联系起来。提交表格后,我想将学生及其相关事件插入数据库。所以我写了这段代码:
$db = new PDO('mysql:host=localhost;dbname=school;charset=utf8','root', '****');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$sql = "INSERT INTO pupil
(name, surname)
VALUES
('test_name', 'test_surname')";
$st = $db->prepare($sql);
$st->execute();
foreach ($eveningActivityIds as $eveningActivityId) {
$sql = "INSERT INTO pupil_evening_activity
(pupil_id, evening_activity_id)
VALUES
(?, ?)
";
$st = $db->prepare($sql);
$st->execute(array($db->lastInsertId(), $eveningActivityId));
}
} catch (PDOException $e) {
echo $e->getMessage();
return false;
}
我已经编写了代码期望PDO::lastInsertId()
总是返回最后插入的学生的id,但我发现它真正返回的是< strong>整个数据库中最后插入的 id
。因此,如果在上面的代码中 调用 $db->lastInsertId()
之前在假设的 teacher
表中插入了另一行,$db->lastInsertId()
将返回插入的教师的 id
而不是最后一个学生的 id
。
那么在提交表单后,如何才能 100% 安全地获取 pupil
表的最后插入的 id
?
我考虑过使用事务和 MAX()
函数来获取插入到 pupil
表中的最后一个 id
,但我不确定。
最佳答案
在 foreach 循环中使用 $db->lastInsertId() 是错误的,因为它可能返回不可预测的值。请考虑以下代码:
try {
$sql = "INSERT INTO pupil
(name, surname)
VALUES
('test_name', 'test_surname')";
$st = $db->prepare($sql);
$st->execute();
// save pupil id into variable here:
$pupil_id = $db->lastInsertId();
// also there's no need to prepare the statement on each iteration:
$sql = "INSERT INTO pupil_evening_activity
(pupil_id, evening_activity_id)
VALUES
(?, ?)";
$st = $db->prepare($sql);
foreach ($eveningActivityIds as $eveningActivityId) {
$st->execute(array($pupil_id, $eveningActivityId));
}
} catch (PDOException $e) {
echo $e->getMessage();
return false;
}
优化:您可以在一条语句中插入所有事件。它为您节省了一些请求
try {
$sql = "INSERT INTO pupil
(name, surname)
VALUES
('test_name', 'test_surname')";
$st = $db->prepare($sql);
$st->execute();
// save pupil id into variable here:
$pupil_id = $db->lastInsertId();
$sql = 'INSERT INTO pupil_evening_activity
(pupil_id, evening_activity_id)
VALUES ';
$values = array();
foreach ($eveningActivityIds as $eveningActivityId) {
$sql .= '(?, ?),';
array_push($values, $pupil_id, $eveningActivityId);
}
$st = $db->prepare(chop($sql, ','));
$st->execute($values);
} catch (PDOException $e) {
echo $e->getMessage();
return false;
}
关于php - 为 m :m relationship (pupil-evening_activity) consistently 插入行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231995/