我有一个查询,我想将某些数据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
的表是查询所应用的地方。
这就是目前正在发生的事情,因为我需要以某种方式将userTakingModuleID
的主键包含到查询中。 (我几乎要说,要查找哪里有idUser
和ModuleID
相同的条目?)
答案 0 :(得分:2)
使用INSERT...ON DUPLICATE KEY UPDATE
的重要部分是告诉MySQL密钥是什么,以便它可以查找重复项。你说:
我几乎要说一遍,寻找哪里有
idUser
和ModuleID
相同的条目
那是完全正确的。您需要在这两列上创建一个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();