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

PHP/Mysqli批量插入不重复记录:Ajax JSON数据场景实现

PHP/Mysqli批量插入不重复记录(处理嵌套JSON数据)

没问题,我来帮你搞定这个批量插入的需求,还要确保只插不存在的记录,同时处理你给的嵌套JSON结构。下面是一步步的实现方案:

1. 先理清楚需求核心

你需要接收这样的JSON数据:

{"add":{"abc":"123","name":"CompanyName","user_id":"1","portfolios":[{"portfolio_id":"1"},{"portfolio_id":"2"},{"portfolio_id":"3"}]}}

然后把它拆成3条独立记录插入表中,每条记录包含abc、name、user_id、portfolio_id四个字段,并且只插入数据库中不存在的记录,重复的要返回失败提示。

2. 数据库准备(关键!)

首先必须给你的表加一个唯一约束,用来判断记录是否重复。假设你业务里的唯一标识是user_id + portfolio_id的组合(你可以根据实际业务调整),执行这条SQL:

ALTER TABLE your_table_name ADD UNIQUE KEY unique_user_portfolio (user_id, portfolio_id);

有了这个约束,我们才能准确识别重复记录。

3. 完整PHP实现代码

下面是结合Mysqli的安全实现,用预处理语句避免SQL注入,同时处理重复判断:

<?php
// 1. 数据库连接(替换成你的数据库信息)
$mysqli = new mysqli('localhost', 'your_username', 'your_password', 'your_database');
if ($mysqli->connect_error) {
    die(json_encode(['status' => 'error', 'message' => '数据库连接失败: ' . $mysqli->connect_error]));
}

// 2. 接收并解析Ajax传来的JSON数据
$json_input = file_get_contents('php://input');
$request_data = json_decode($json_input, true);

// 3. 验证输入数据的合法性
if (!isset($request_data['add'], $request_data['add']['abc'], $request_data['add']['name'], $request_data['add']['user_id'], $request_data['add']['portfolios']) || !is_array($request_data['add']['portfolios'])) {
    echo json_encode(['status' => 'error', 'message' => '输入数据格式不正确']);
    $mysqli->close();
    exit;
}

// 4. 提取基础字段和portfolio列表
$base_fields = [
    'abc' => $request_data['add']['abc'],
    'name' => $request_data['add']['name'],
    'user_id' => $request_data['add']['user_id']
];
$portfolio_list = $request_data['add']['portfolios'];

// 5. 整理待插入的记录数组
$all_records = [];
$portfolio_ids = [];
foreach ($portfolio_list as $item) {
    if (isset($item['portfolio_id'])) {
        $all_records[] = [
            ...$base_fields,
            'portfolio_id' => $item['portfolio_id']
        ];
        $portfolio_ids[] = $item['portfolio_id'];
    }
}

if (empty($all_records)) {
    echo json_encode(['status' => 'error', 'message' => '没有有效的记录需要插入']);
    $mysqli->close();
    exit;
}

// 6. 查询数据库中已存在的记录
$placeholders = implode(',', array_fill(0, count($portfolio_ids), '?'));
$check_sql = "SELECT portfolio_id FROM your_table_name WHERE user_id = ? AND portfolio_id IN ($placeholders)";
$stmt = $mysqli->prepare($check_sql);

// 绑定参数(注意:如果user_id/portfolio_id是字符串,把类型符从'i'改成's')
$param_types = 'i' . str_repeat('i', count($portfolio_ids));
$params = array_merge([$param_types, $base_fields['user_id']], $portfolio_ids);
call_user_func_array([$stmt, 'bind_param'], $params);

$stmt->execute();
$result = $stmt->get_result();
$existing_ids = [];
while ($row = $result->fetch_assoc()) {
    $existing_ids[] = $row['portfolio_id'];
}
$stmt->close();

// 7. 筛选出需要插入的新记录
$new_records = array_filter($all_records, function($record) use ($existing_ids) {
    return !in_array($record['portfolio_id'], $existing_ids);
});

if (empty($new_records)) {
    echo json_encode([
        'status' => 'error',
        'message' => '所有记录都已存在',
        'existing_portfolio_ids' => $existing_ids
    ]);
    $mysqli->close();
    exit;
}

// 8. 批量插入新记录
$columns = implode(',', array_keys($new_records[0]));
$value_groups = [];
$insert_params = [];
$insert_types = '';

foreach ($new_records as $record) {
    $value_groups[] = '(' . implode(',', array_fill(0, count($record), '?')) . ')';
    foreach ($record as $val) {
        $insert_params[] = $val;
        // 根据字段类型设置类型符:整数'i',字符串's',浮点'd'
        $insert_types .= is_int($val) ? 'i' : 's';
    }
}

$insert_sql = "INSERT INTO your_table_name ($columns) VALUES " . implode(',', $value_groups);
$stmt = $mysqli->prepare($insert_sql);
call_user_func_array([$stmt, 'bind_param'], array_merge([$insert_types], $insert_params));

if ($stmt->execute()) {
    $inserted_count = $stmt->affected_rows;
    echo json_encode([
        'status' => 'success',
        'message' => "成功插入 $inserted_count 条记录",
        'inserted_records' => $new_records,
        'existing_portfolio_ids' => $existing_ids
    ]);
} else {
    echo json_encode(['status' => 'error', 'message' => '插入失败: ' . $stmt->error]);
}

// 9. 关闭连接
$stmt->close();
$mysqli->close();
?>

4. 关键细节说明

  • SQL注入防护:全程使用Mysqli预处理语句,避免直接拼接SQL字符串。
  • 重复判断逻辑:先批量查询已存在的记录,再筛选出需要插入的新记录,比逐条判断效率高很多。
  • 返回结果:接口会返回清晰的JSON格式结果,包含成功/失败状态、提示信息,以及已存在的ID列表,方便前端处理。
  • 字段类型适配:代码里默认user_id和portfolio_id是整数,如果你的字段是字符串,记得把参数类型符从i改成s。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:29:06