ON DUPLICATE KEY查询 - 拉出表的主键

问题描述 投票:1回答:1

我有一个查询,我想INSERT一些数据到我的表,但是,如果已经有特定字段checkPoint内的数据,然后运行UPDATE。经过大量的研究,用户建议使用ON DUPLICATE KEY。

然而,这个查询可以用来更新已经存在的行,它会插入一个新的,带有一个新的主键,请有人解释我哪里出错了,或者我错过了什么。

<?php
      $idUsers = $_SESSION['id'];
      $ModuleID = 5;
      $checkPoint = 999;

      $query= "INSERT INTO `userTakingModule` (`userTakingModuleID`, `idUsers`, `ModuleID`, `checkPoint`) VALUES (NULL, $idUsers, $ModuleID, $checkPoint) ON DUPLICATE KEY UPDATE `idUsers` = VALUES ($idUsers), `ModuleID` = VALUES ($ModuleID), `checkPoint` = VALUES ($checkPoint) "; 

      $result = $conn -> query($query);
?>

我的数据库布局的屏幕截图:中间名为userTakingModule的表是应用查询的位置。

<code>checkPoint</code> Screenshot

这就是目前正在发生的事情,因为我需要以某种方式将userTakingModuleID的主键包含在查询中。 (我几乎要说,找一下同一个idUserModuleID已经存在的条目?)

Table Screenshot

php mysql pdo
1个回答
2
投票

使用INSERT...ON DUPLICATE KEY UPDATE的重要部分是告诉MySQL关键是什么,因此它可以查找重复项。你说:

我几乎需要说,寻找已经存在的相同idUserModuleID的条目

这是完全正确的。您需要在这两列上创建一个UNIQUE索引,如下所示:

ALTER TABLE userTakingModule ADD UNIQUE INDEX(idUser, ModuleID);

现在,冲突将触发更新功能。您应该只从查询中删除userTakingModuleID列,它将根据需要自动赋值。你也误用了VALUES函数;你应该传递一个列名,它将解析为插入该列而没有冲突的值。所以你可以使用VALUES函数或变量本身。

说到变量,如果我没有指出将变量直接插入到查询中是多么不安全和危险,我会失职。您应该始终使用预准备语句。您没有提供足够的代码来了解您正在使用的数据库API,但对于PDO,它看起来像这样:

  $idUsers = $_SESSION['id'];
  $ModuleID = 5;
  $checkPoint = 999;

  $query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
  $stmt = $conn->prepare($query);
  $stmt->execute([$idUsers, $ModuleID, $checkPoint]);
  $data = $stmt->fetchAll(\PDO::FETCH_ASSOC);

而对于mysqli这样的东西(虽然我不太熟悉它)

  $idUsers = $_SESSION['id'];
  $ModuleID = 5;
  $checkPoint = 999;

  $query= "INSERT INTO userTakingModule (idUsers, ModuleID, checkPoint) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE idUsers = VALUES (idUsers), ModuleID = VALUES (ModuleID), checkPoint = VALUES (checkPoint)";
  $stmt = $conn->prepare($query);
  $stmt->bind_param("iii", $idUsers, $ModuleID, $checkPoint);
  $stmt->execute();
  $result = $stmt->get_result();
© www.soinside.com 2019 - 2024. All rights reserved.