始终为 m:m 关系 (pupil-evening_activity) 插入行
Posted
技术标签:
【中文标题】始终为 m:m 关系 (pupil-evening_activity) 插入行【英文标题】:Insert rows for an m:m relationship (pupil-evening_activity) consistently 【发布时间】:2017-05-28 21:02:46 【问题描述】:我的数据库 (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,但我发现它真正返回的是最后插入的id
整个数据库。因此,如果在假设的teacher
表中插入另一行就在 在上面的代码中调用$db->lastInsertId()
,$db->lastInsertId()
将返回插入教师的id
而不是@987654334最后一个学生的@。
那么在提交表单后,我如何才能在pupil
表的最后插入id
获得100% 的安全性?
我曾考虑使用事务和MAX()
函数将最后一个id
插入pupil
表中,但我不确定。
【问题讨论】:
【参考方案1】:在 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;
【讨论】:
谢谢!很有用!!但是..对我的主要问题有什么想法吗?即:使用PDO::lastInsertId()
将最后一个id
插入pupil
表中是否正确?
我相信这很好,除非你正在构建一个每秒有数千个请求的高负载系统 J.以上是关于始终为 m:m 关系 (pupil-evening_activity) 插入行的主要内容,如果未能解决你的问题,请参考以下文章