我有一个查询,我想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
已经存在的条目?)
使用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();