#php #mysql #pdo
#php #mysql #pdo
Вопрос:
У меня есть запрос, который я хотел бы INSERT
добавить некоторые данные в мою таблицу, однако, если внутри определенного поля уже есть данные checkPoint
, затем запустите UPDATE
. После долгих исследований здесь пользователи предложили использовать ДУБЛИКАТ КЛЮЧА.
Этот запрос работает, однако, в соответствии с обновлением уже существующей строки, он вставляет новую с новым первичным ключом, пожалуйста, может кто-нибудь объяснить, где я ошибся, или что я пропустил.
<?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
?)
Ответ №1:
Важной частью использования INSERT...ON DUPLICATE KEY UPDATE
является указание MySQL, что это за ключ, чтобы он мог искать дубликаты. Вы сказали:
Мне почти нужно сказать, ищите, где есть уже существующая запись того же
idUser
иModuleID
И это совершенно верно. Вам нужно создать УНИКАЛЬНЫЙ индекс для этих двух столбцов следующим образом:
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();
Комментарии:
1. Привет @miken32 большое спасибо за вашу помощь, так что я должен просто полностью избавиться от первичного ключа в
userTakingModule
таблицеuserTakingModuleID
idUser, ModuleID
, а затем создать новый первичный ключ из,,?2. ВЫ ГЕНИЙ, я использую PDO, поэтому сделал его безопаснее с вашим предложением, могу я просто сказать вам большое спасибо, я пытался работать над этим так долго, я был так близок, ха-ха, и вы решили это! Приятного вечера 🙂
3. Ха, просто делайте это в течение 20 лет, и вы тоже сможете вытащить этот материал из шляпы в любой момент.
4. Просто очень быстрый вопрос, в версии mysqli, которую я использую, как в запросе обновления, где говорится
idUsers = VALUES (idUsers)
и т.д., Он знает значение для ввода, если оно не принимается переменными? (нужно хорошо выспаться, решив это в моей голове, лол). Это просто относится к переменным, переданным на стороне ВСТАВКИ запроса?5. dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html «Другими словами,
VALUES(col_name)
вON DUPLICATE KEY UPDATE
предложении относится к значениюcol_name
, которое было бы вставлено, если бы не возникло конфликта с дубликатом ключа».