php - 为 m :m relationship (pupil-evening_activity) consistently 插入行

标签 php mysql pdo many-to-many last-insert-id

我的数据库 (MySQL/InnoDB) 中有三个表:pupilevening_activitypupil_evening_activity。您可以猜到,pupilevening_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/

相关文章:

php - 如何从javascript调用表单提交?

php - 拉拉维尔 5.1 : how can i get nested relation from model?

php - 我的 PHP 表单发送数据,但 sql 显示所有列零记录

php - 事务回滚不起作用

php - 使用 PHP/PDO 将 SQL 脚本运行到 PostgreSQL

php - SQLSRV 从 MySQL 转换数据表时参数无效

php - htaccess 重定向基于存储在数据库中的 URL

PHP获取文件夹名称按创建日期排序

php - mysql 将三个查询合并为一个

sql - 不需要的 MySQL 索引