php—如何检查数据库中是否存在元素并返回警告消息?

8gsdolmq  于 2021-07-26  发布在  Java
关注(0)|答案(1)|浏览(473)

我有一个例子,我正在导入一个项目的电子表格,在插入时,我需要检查每个项目是否已经存在(通过serial\u no或serial\u imei),然后对于每个存在的项目,我需要在提交完成时通知用户一条消息,例如:“数据库中已找到序列号为123456的项目”。
以下是我插入的方式:

  1. $stmt = $db->prepare("INSERT INTO devices (serial_imei,serial_no) VALUES (?,?)");
  2. for ($i = 0; $i < $min; $i++) {
  3. $stmt->bind_param("ii", $imei[$keysTwo[$i]], $serial_no[$keysOne[$i]]);
  4. $stmt->execute();
  5. }

我看到了一个可以使用insert ignore的地方,但是如何在内部循环中使用它并为找到的每个项返回警告消息呢?

qv7cva1a

qv7cva1a1#

假设您在这两者上都有一个复合唯一键 serial_imei 以及 serial_no 您可以捕获异常,检查mysql错误代码是否为1062(重复条目),并将这些行收集到一个表中。然后可以向用户显示该表,以告知哪些表已经存在。
让我用下面代码的一个例子来说明这一点:

  1. $imei = [1111, 2222];
  2. $serial_no = [3333, 4444];
  3. $min = 2;
  4. // We will collect all duplicate keys to be displayed later
  5. $duplicates = [];
  6. $stmt = $mysqli->prepare("INSERT INTO devices (serial_imei,serial_no) VALUES (?,?)");
  7. for ($i = 0; $i < $min; $i++) {
  8. $stmt->bind_param('ss', $imei[$i], $serial_no[$i]);
  9. // execute() is wrapped in try-catch to catch the exception from MySQL
  10. try {
  11. $stmt->execute();
  12. } catch (\mysqli_sql_exception $e) {
  13. // We are only interested in 1062 (duplicate entry) and we want to rethrow anything else
  14. if ($e->getCode() !== 1062) {
  15. // If not 1062 then rethrow
  16. throw $e;
  17. }
  18. $duplicates[] = ['imei' => $imei[$i], 'no' => $serial_no[$i]];
  19. }
  20. }
  21. foreach ($duplicates as $dup) {
  22. echo "Duplicate! IMEI:{$dup['imei']} Serial No.:{$dup['no']} ".PHP_EOL;
  23. }

如果出于某种原因,列没有唯一约束,那么在插入行之前,需要执行并行select语句以查看行是否存在。这稍微复杂一点,可能也慢一点。如果这样做,则必须首先获取表上的锁,以确保没有其他进程同时插入重复的行。

  1. $duplicates = [];
  2. $mysqli->autocommit(0);
  3. $mysqli->query('LOCK TABLES devices WRITE');
  4. // SELECT stmt
  5. $select_stmt = $mysqli->prepare("SELECT COUNT(1) FROM devices WHERE serial_imei=? AND serial_no=?");
  6. // INSERT stmt
  7. $stmt = $mysqli->prepare("INSERT INTO devices (serial_imei,serial_no) VALUES (?,?)");
  8. for ($i = 0; $i < $min; $i++) {
  9. // First execute SELECT to check if the value exists already
  10. $select_stmt->bind_param('ss', $imei[$i], $serial_no[$i]);
  11. $select_stmt->execute();
  12. $exists = $select_stmt->get_result()->fetch_row()[0];
  13. if ($exists) {
  14. $duplicates[] = ['imei' => $imei[$i], 'no' => $serial_no[$i]];
  15. } else {
  16. // No result was found in DB, let's insert
  17. $stmt->bind_param('ss', $imei[$i], $serial_no[$i]);
  18. $stmt->execute();
  19. }
  20. }
  21. $mysqli->autocommit(1);
  22. $mysqli->query('UNLOCK TABLES');
展开查看全部

相关问题