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

MySQL双表数据同步问题:JSON数据实现新增/更新逻辑

问题解决方案与代码错误分析

一、核心逻辑实现思路

三个表通过userid关联,判断客户是否存在的核心依据是**tblcustomfieldsvalues.value字段的唯一客户编码**(业务唯一标识),以此展开「存在则更新,不存在则插入」的逻辑:

  1. 存在:通过编码找到对应的relid(即tblclients.userid),更新tblclients和tblcontacts的对应数据
  2. 不存在:先插入tblclients获取自增userid,再依次插入tblcustomfieldsvalues和tblcontacts关联数据

二、现有插入代码的典型错误

假设你的现有代码类似以下结构,这些是高频问题:

// 错误示例代码
$jsonData = json_decode($curlResponse, true);
// 错误1:$email未赋值就执行判断
if (empty($email)) {
    $email = $jsonData['email'];
}
// 错误2:变量重复使用,$userid既存查询结果集又存自增ID
$userid = mysqli_query($conn, "SELECT userid FROM tblclients WHERE email = '$email'");
// 错误3:直接拼接外部数据,存在SQL注入风险
mysqli_query($conn, "INSERT INTO tblclients (name, email) VALUES ('{$jsonData['name']}', '$email')");
$userid = mysqli_insert_id($conn);
// 错误4:未检查数据库操作结果,无错误排查能力
mysqli_query($conn, "INSERT INTO tblcustomfieldsvalues (relid, value) VALUES ('$userid', '{$jsonData['customercode']}')");

对应错误点:

  • 未赋值就判断变量:$email还未从JSON提取就执行empty($email),逻辑完全颠倒
  • 变量重复覆盖:同一个$userid既存储查询结果对象,又存储自增ID数值,导致后续逻辑混乱
  • SQL注入风险:直接将外部JSON数据拼接进SQL语句,未做参数绑定处理
  • 缺乏错误处理:没有检查数据库操作的返回结果,无法定位插入失败原因
  • 关联逻辑缺失:未通过唯一客户编码判断存在性,直接插入会产生重复数据

三、完整实现代码

<?php
// 假设已建立mysqli数据库连接$conn
$jsonData = json_decode($curlResponse, true);
$customercode = $jsonData['customercode'];
$clientName = $jsonData['name'];
$clientEmail = $jsonData['email'];
$contactPhone = $jsonData['contact_phone'];

// 第一步:通过唯一客户编码查询是否存在该客户
$stmt = $conn->prepare("SELECT relid FROM tblcustomfieldsvalues WHERE value = ?");
$stmt->bind_param("s", $customercode);
$stmt->execute();
$result = $stmt->get_result();
$existingUserId = null;

if ($result->num_rows > 0) {
    // 客户存在,更新关联表数据
    $row = $result->fetch_assoc();
    $existingUserId = $row['relid'];

    // 更新tblclients
    $stmtUpdateClient = $conn->prepare("UPDATE tblclients SET name = ?, email = ? WHERE userid = ?");
    $stmtUpdateClient->bind_param("ssi", $clientName, $clientEmail, $existingUserId);
    $stmtUpdateClient->execute();
    $stmtUpdateClient->close();

    // 更新tblcontacts(可根据实际业务调整更新字段和条件)
    $stmtUpdateContact = $conn->prepare("UPDATE tblcontacts SET phone = ? WHERE userid = ?");
    $stmtUpdateContact->bind_param("si", $contactPhone, $existingUserId);
    $stmtUpdateContact->execute();
    $stmtUpdateContact->close();
} else {
    // 客户不存在,插入关联表数据
    // 插入tblclients并获取自增userid
    $stmtInsertClient = $conn->prepare("INSERT INTO tblclients (name, email) VALUES (?, ?)");
    $stmtInsertClient->bind_param("ss", $clientName, $clientEmail);
    $stmtInsertClient->execute();
    $newUserId = $conn->insert_id;
    $stmtInsertClient->close();

    // 插入tblcustomfieldsvalues
    $stmtInsertCustom = $conn->prepare("INSERT INTO tblcustomfieldsvalues (relid, value) VALUES (?, ?)");
    $stmtInsertCustom->bind_param("is", $newUserId, $customercode);
    $stmtInsertCustom->execute();
    $stmtInsertCustom->close();

    // 插入tblcontacts
    $stmtInsertContact = $conn->prepare("INSERT INTO tblcontacts (userid, phone) VALUES (?, ?)");
    $stmtInsertContact->bind_param("is", $newUserId, $contactPhone);
    $stmtInsertContact->execute();
    $stmtInsertContact->close();
}

// 释放资源
$stmt->close();
$conn->close();
?>

四、关键说明

  • 存在性判断标准:优先使用业务唯一的客户编码,而非邮箱或名称(邮箱可变更、名称易重复)
  • 安全处理:全程使用mysqli预处理语句绑定参数,彻底规避SQL注入
  • 变量隔离:用$existingUserId和$newUserId分别存储已有客户ID和新增客户ID,避免变量覆盖
  • 调试建议:可在每个数据库操作后添加if (!$stmt->execute()) { echo $stmt->error; }捕获错误,方便排查问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:05:20