Запрос ON DUPLICATE KEY - извлечение первичного ключа таблицы - PullRequest
1 голос
/ 23 апреля 2019

У меня есть запрос, который я бы хотел 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 в середине - это то место, к которому применяется запрос.

imagecheckPoint Screenshot">

Это то, что происходит в данный момент, так как мне нужно как-то включить Первичный ключ userTakingModuleID в запрос. (Мне почти нужно сказать, ищите, где находится уже существующая запись того же idUser и ModuleID?)

Table Screenshot

1 Ответ

2 голосов
/ 23 апреля 2019

Важной частью использования 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...