ПРИ запросе ДУБЛИКАТА КЛЮЧА — извлечение первичного ключа таблицы

#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 в середине, — это то, к чему применяется запрос.

<код>Контрольная точка</code> Скриншот

Это то, что происходит в данный момент, поскольку мне нужно каким-то образом включить первичный ключ 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 , которое было бы вставлено, если бы не возникло конфликта с дубликатом ключа».