使用外键时更改 LAST_INSERT_ID()

Posted

技术标签:

【中文标题】使用外键时更改 LAST_INSERT_ID()【英文标题】:LAST_INSERT_ID() is changed while using foreign key 【发布时间】:2017-09-06 07:41:06 【问题描述】:

我的项目中有 5 个表(A、B、C、D、E)。

一个表的 PK sysNum 是 int(255) NOT NULL AUTO_INCREMENT。

B 的 PK sheetNum 是 int(255) NOT NULL AUTO_INCREMENT,B 有 FK sysNum REFERENCES A ON DELETE CASCADE ON UPDATE CASCADE。

C 和 D 具有相同的 FK sheetNum REFERENCES B ON DELETE CASCADE ON UPDATE CASCADE。

E 有 FK sysNum REFERENCES A ON DELETE CASCADE ON UPDATE CASCADE。

我有很多数据要插入到这些表中,所以我选择了事务。这是我的 php 代码:

  $conn->beginTransaction();  
     ......
      $query="insert into A( ) VALUES ();";
      $stmt=$conn->query($query);
      $stmt->closeCursor();

      $query="insert into B (...,sysNum) VALUES(...,LAST_INSERT_ID());
      insert into C (...,sheetNum) VALUES(...,LAST_INSERT_ID());                  
      insert into D (...,sheetNum) VALUES(...,LAST_INSERT_ID());";
      $stmt=$conn->query($query);
      $stmt->closeCursor();

      for($i=5;$i<$eRN;$i++)
     
      ......
      $query="insert into C (...,sheetNum) VALUES (...,LAST_INSERT_ID());";
      $stmt=$conn->query($query);
      $stmt->closeCursor();      
     

     for($i=1;$i<$dRN;$i++)
     
      ......
      $query="insert into D (...,sheetNum) VALUES (...,LAST_INSERT_ID());";
      $stmt=$conn->query($query);
      $stmt->closeCursor();      
     
     ...
     $query="insert into E (sysNum,...) VALUES (LAST_INSERT_ID(),...);";
     $stmt=$conn->query($query);
     $stmt->closeCursor();       

     $query="insert into E (sysNum,...) values (LAST_INSERT_ID(),...);";
     $stmt=$conn->query($query);
     $stmt->closeCursor();
     $conn->commit();

插入A后,auto_increment创建的sysNum为20。插入B后,sheetNum为10,和A一样。所以C和D的sheetNum都是10。但是E的sysNum是10 ,而不是 20。

注意:这 5 个表工作正常,在我将列添加到 A 之前。我设置了 foreign_key_checks=0,并在 A 中添加了一个新列。然后又设置了 foreign_key_checks=1,但不幸的是 E 表工作失败。

我不知道,谁能帮帮我?

【问题讨论】:

【参考方案1】:

当以这种方式使用 LAST_INSERT_ID() 时,您将始终从 latest SQL 语句中获取值,这是您插入 B 的关键。 我认为你想要的是最后一条 SQL 语句,它具有先前语句的值。完成 A 的插入后,最好存储此值。您可以使用(用于 PDO)

$query="insert into A( ) VALUES ();";
$stmt=$conn->query($query);
$id = Sconn->lastInsertId();

对于 mysqli...

$query="insert into A( ) VALUES ();";
$stmt=$conn->query($query);
$id = Sconn->insert_id;

然后将此值用于表 E 中的插入。

【讨论】:

我试过 $id = $conn->insert_id;插入 E (sysNum,...) 值 ($id,...);但 $id 为空 你是在插入表 A 之后才放这个的吗?更新了答案以及应该放置的位置。 对于 PDO - 您需要改用 lastInsertId() 插入A后,我设置$id = LAST_INSERT_ID();插入 E (sysNum,...) 值 ($id,...);但也失败了 您必须像代码示例中那样设置 $id 而不是 LAST_INSERT_ID()

以上是关于使用外键时更改 LAST_INSERT_ID()的主要内容,如果未能解决你的问题,请参考以下文章

contentType 应用,(表中数据大量存在外键时使用)

ERROR 1005 (HY000): 使用外键时无法创建表

父模型具有多个外键时的Django外键反向访问[重复]

无法检索记录使用jpa库外键时为空

Django - 删除外键时删除数据库条目

创建外键时,phpmyadmin 中的外键约束失败