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

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

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

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

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

qv7cva1a

qv7cva1a1#

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

$imei = [1111, 2222];
$serial_no = [3333, 4444];
$min = 2;

// We will collect all duplicate keys to be displayed later
$duplicates = [];

$stmt = $mysqli->prepare("INSERT INTO devices (serial_imei,serial_no) VALUES (?,?)");
for ($i = 0; $i < $min; $i++) {
    $stmt->bind_param('ss', $imei[$i], $serial_no[$i]);

    // execute() is wrapped in try-catch to catch the exception from MySQL
    try {
        $stmt->execute();
    } catch (\mysqli_sql_exception $e) {
        // We are only interested in 1062 (duplicate entry) and we want to rethrow anything else
        if ($e->getCode() !== 1062) {
            // If not 1062 then rethrow
            throw $e;
        }

        $duplicates[] = ['imei' => $imei[$i], 'no' => $serial_no[$i]];
    }
}

foreach ($duplicates as $dup) {
    echo "Duplicate! IMEI:{$dup['imei']} Serial No.:{$dup['no']} ".PHP_EOL;
}

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

$duplicates = [];

$mysqli->autocommit(0);
$mysqli->query('LOCK TABLES devices WRITE');

// SELECT stmt
$select_stmt = $mysqli->prepare("SELECT COUNT(1) FROM devices WHERE serial_imei=? AND serial_no=?");
// INSERT stmt
$stmt = $mysqli->prepare("INSERT INTO devices (serial_imei,serial_no) VALUES (?,?)");

for ($i = 0; $i < $min; $i++) {
    // First execute SELECT to check if the value exists already
    $select_stmt->bind_param('ss', $imei[$i], $serial_no[$i]);
    $select_stmt->execute();
    $exists = $select_stmt->get_result()->fetch_row()[0];
    if ($exists) {
        $duplicates[] = ['imei' => $imei[$i], 'no' => $serial_no[$i]];
    } else {
        // No result was found in DB, let's insert
        $stmt->bind_param('ss', $imei[$i], $serial_no[$i]);
        $stmt->execute();
    }
}

$mysqli->autocommit(1);
$mysqli->query('UNLOCK TABLES');

相关问题