You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

批量插入dr_scan表遇重复值时出现MySQL子查询返回多行错误

问题描述

我在dr_scan表中有scan_freq字段,需求是:向该表插入记录时,若要插入的barcode值已存在于表中,就将原有重复行的scan_freq设为0;若不存在,新插入行的scan_freq设为1。

我写了下面的代码,单条插入时符合预期,但批量插入包含重复值的记录时,出现subquery returns more than 1 row错误。

if ($savec == "confirm") 
{ 
    $checkIfExistsQuery = "SELECT COUNT(*) as count FROM dr_scan WHERE barcode = (SELECT barcode FROM temp_scan_save WHERE user_id='$user_id' )"; 
    $checkResult = mysqli_query($conn, $checkIfExistsQuery); 
    $rowCount = mysqli_fetch_assoc($checkResult)['count']; 
    if ($rowCount > 0) 
    {
         $updateSql = "UPDATE dr_scan SET scan_freq = 0 WHERE barcode = (SELECT barcode FROM temp_scan_save WHERE user_id='$user_id' )"; 
         $updateResult = mysqli_query($conn, $updateSql); 
     } 
        $insertSql = "INSERT INTO dr_scan (barcode, machine_type, line, date, user_id, device_id, center, mstatus, mstatus_changed, live_status, transfer_status, scan_freq) SELECT barcode, machine_type, line, date, user_id, device_id, center, mstatus, mstatus_changed, live_status, transfer_status, 1 as scan_frequency FROM temp_scan_save WHERE user_id='$user_id'"; 
        $insertResult = mysqli_query($conn, $insertSql); 
        if (isset($updateResult) && $updateResult && isset($insertResult) && $insertResult)
         { $response = array("response" => "success"); echo json_encode($response); 
        } else 
        { 
            $response = array("response" => "failure"); echo json_encode($response);
         } 
         $sql2 = "DELETE FROM temp_scan_save WHERE user_id='$user_id' "; $result2 = mysqli_query($conn, $sql2); } 
         else { }
mysqli_close($conn);

解决方案

错误根源

批量插入时,temp_scan_save表会返回多个barcode值,但你用了只能匹配单个值的=运算符,导致子查询返回多行时触发报错。需要把=替换成支持多值匹配的IN。

另外原代码的判断逻辑有漏洞:如果不需要执行更新(无重复barcode),$updateResult变量未定义,会导致判断失败。

修改后的代码

if ($savec == "confirm") {
    // 用IN替代=,适配子查询返回多个barcode的情况
    $checkIfExistsQuery = "SELECT COUNT(*) as count FROM dr_scan WHERE barcode IN (SELECT barcode FROM temp_scan_save WHERE user_id='$user_id')";
    $checkResult = mysqli_query($conn, $checkIfExistsQuery);
    $rowCount = mysqli_fetch_assoc($checkResult)['count'];

    $updateResult = true; // 默认更新成功(无重复时无需执行更新)
    if ($rowCount > 0) {
        // 同样把=改成IN
        $updateSql = "UPDATE dr_scan SET scan_freq = 0 WHERE barcode IN (SELECT barcode FROM temp_scan_save WHERE user_id='$user_id')";
        $updateResult = mysqli_query($conn, $updateSql);
    }

    $insertSql = "INSERT INTO dr_scan (barcode, machine_type, line, date, user_id, device_id, center, mstatus, mstatus_changed, live_status, transfer_status, scan_freq) 
                  SELECT barcode, machine_type, line, date, user_id, device_id, center, mstatus, mstatus_changed, live_status, transfer_status, 1 as scan_freq 
                  FROM temp_scan_save WHERE user_id='$user_id'";
    $insertResult = mysqli_query($conn, $insertSql);

    // 优化判断逻辑:无重复时只校验插入结果;有重复时同时校验更新和插入结果
    if (($rowCount == 0 && $insertResult) || ($rowCount > 0 && $updateResult && $insertResult)) {
        $response = ["response" => "success"];
        echo json_encode($response);
    } else {
        $response = ["response" => "failure"];
        echo json_encode($response);
    }

    $sql2 = "DELETE FROM temp_scan_save WHERE user_id='$user_id'";
    $result2 = mysqli_query($conn, $sql2);
}

mysqli_close($conn);

额外优化建议

  • 防SQL注入:直接拼接$user_id存在注入风险,建议改用预处理语句:
// 示例:预处理查询重复数量
$checkStmt = $conn->prepare("SELECT COUNT(*) as count FROM dr_scan WHERE barcode IN (SELECT barcode FROM temp_scan_save WHERE user_id=?)");
$checkStmt->bind_param("s", $user_id); // 若user_id是整数,把"s"改成"i"
$checkStmt->execute();
$checkResult = $checkStmt->get_result();
$rowCount = mysqli_fetch_assoc($checkResult)['count'];
$checkStmt->close();
  • 保证操作原子性:如果需要更新、插入、删除三个操作要么全部成功要么全部回滚,可以用事务包裹:
$conn->begin_transaction();
try {
    // 执行更新、插入、删除逻辑
    $conn->commit();
    echo json_encode(["response" => "success"]);
} catch (Exception $e) {
    $conn->rollback();
    echo json_encode(["response" => "failure"]);
}

内容的提问来源于stack exchange,提问作者Pasindu Hettiarachchi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:11:05