PHP实现从两张数据库表取数并插入新表问题求助
修复从input和out_materials表同步数据到total表的PHP代码
我先梳理下你的代码存在的几个关键问题,然后给出修正后的完整解决方案:
原代码的核心问题
- 字段名不匹配:你的数据表字段是
in_qty、out_qty、unit,但代码里错误写成了Input_qty、Out_qty、Unit,MySQL在大小写敏感的环境下会找不到对应字段。 - 重复字段覆盖:
SELECT i.*, o.*会导致两个表的同名字段(比如Materials_code、Materials_name、unit)被覆盖,你无法正确获取两个表的对应字段值。 - 变量作用域问题:你在
while循环内定义的变量,循环结束后只会保留最后一条数据的内容;如果查询无结果,变量会直接未定义,导致插入失败。 - 缺乏错误处理:没有检查SQL查询是否执行成功,无法快速定位问题根源。
- SQL注入风险:直接将变量拼接到INSERT语句中,存在严重的安全隐患。
- 忽略total表的
Qty字段:total表需要计算in_qty - out_qty作为Qty值,原代码完全没处理这个必填字段。
修正后的完整代码
// 先确认数据库连接正常(假设$con已正确初始化) if (!$con) { die("数据库连接失败: " . mysqli_connect_error()); } // 用明确字段查询,避免重复字段覆盖,关联条件用更可靠的物料编码(比名称唯一) $sql = "SELECT i.Materials_code, i.Materials_name, i.unit, i.in_qty, o.out_qty FROM input i JOIN out_materials o ON i.Materials_code = o.Materials_code"; $res = mysqli_query($con, $sql); // 检查查询是否成功 if (!$res) { die("查询失败: " . mysqli_error($con)); } // 循环处理每一条匹配的数据 while ($row = mysqli_fetch_assoc($res)) { // 计算库存结余数量 $qty = $row['in_qty'] - $row['out_qty']; // 使用预处理语句防止SQL注入,同时正确映射所有字段 $stmt = mysqli_prepare($con, "INSERT INTO total (Materials_code, Materials_name, unit, in_qty, out_qty, Qty) VALUES (?, ?, ?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, "sssiii", $row['Materials_code'], $row['Materials_name'], $row['unit'], $row['in_qty'], $row['out_qty'], $qty ); // 执行插入并反馈结果 if (mysqli_stmt_execute($stmt)) { echo "一条物料数据插入成功<br>"; } else { echo "插入失败: " . mysqli_stmt_error($stmt) . "<br>"; } mysqli_stmt_close($stmt); } // 释放资源并关闭连接 mysqli_free_result($res); mysqli_close($con);
关键优化点说明
- 明确字段查询:不再用模糊的
SELECT *,而是指定需要的字段,通过表别名区分,彻底解决重复字段覆盖的问题。 - 标准JOIN语法:用
JOIN替代旧的逗号分隔表写法,逻辑更清晰;关联条件选择Materials_code(物料编码通常是唯一标识,比物料名称更可靠)。 - 预处理语句:使用mysqli的预处理绑定参数,既避免了SQL注入,也能自动处理特殊字符的转义问题。
- 全链路错误检查:在连接、查询、插入的每一步都添加错误判断,方便快速定位问题。
- 自动计算结余:插入时直接计算
in_qty - out_qty赋值给Qty字段,完全匹配total表的结构要求。 - 关联数组取值:用
mysqli_fetch_assoc返回关联数组,字段名对应更清晰,避免索引取值的混乱。
内容的提问来源于stack exchange,提问作者Fazlul Hoque Sawrav
相关产品推荐
相关产品推荐

