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

PHP/SQL脚本非调试模式仅执行首条插入,调试模式正常

排查PHP/SQL脚本仅插入第一条记录的问题

我来帮你搞定这个诡异的问题——明明调试模式下输出的所有INSERT语句都合法,非调试模式却只插第一条,还没改代码突然炸了,这种情况我碰到好几次,大概率是以下几个原因,按优先级排查:

1. 某条SQL执行失败但没被捕获,中断了有效插入

mysql_query()这个老函数坑就坑在:执行失败时只会返回false,但不会自动终止脚本。非调试模式下,第一条INSERT成功后,后面某条语句因为主键重复、字段类型不匹配、数据长度超限等原因执行失败,脚本还在继续跑,但后续的INSERT都没生效,你却完全不知道。

解决办法:立刻加错误捕获

把你的非调试代码改成这样,把错误信息打出来或者写入日志:

} else {
    // 执行SQL并捕获错误
    $result = mysql_query($query);
    if (!$result) {
        // 测试阶段可以直接输出错误,上线后建议写入日志
        echo "执行失败的SQL:{$query}<br>";
        echo "MySQL错误信息:" . mysql_error() . "<br><hr>";
        // 或者写入服务器日志
        error_log("INSERT失败:{$query} | 错误:" . mysql_error());
    }
}

跑一次就能看到哪条语句出问题了,比如可能是某个position字段的值是空字符串,导致SQL变成position = ,直接语法错误。

2. 脚本超时或内存耗尽

调试模式下有var_dump和<br>输出,执行速度慢,反而没触发超时;非调试模式执行快,但数据量一大,可能在循环中触发了PHP的超时限制或者内存不够,脚本中途直接挂掉,后面的记录自然插不进去。

排查办法:临时调整参数测试

在脚本开头加这两行,取消超时限制并调高内存:

set_time_limit(0); // 临时取消执行时间限制(仅测试用)
ini_set('memory_limit', '256M'); // 根据数据量调整,比如512M

如果这样能插入所有记录,就去修改php.ini里的max_execution_time和memory_limit参数,或者优化循环逻辑减少内存占用。

3. 循环变量或数据隐性异常

虽然调试时看到全量数据,但非调试模式下可能出现:

  • 循环变量$i被意外修改(比如循环里某个地方不小心写了$i++两次);
  • 某些字段值在非调试模式下是空值/非法值(比如$this->data['drivers']['position'][$i]在非调试时变成了null,导致SQL里的position = 语法错误)。

排查办法:在非调试模式下输出关键变量

比如在循环里加一行:

// 非调试模式也输出循环索引和关键字段值,测试用
error_log("循环索引:{$i} | position值:{$this->data['drivers']['position'][$i]}");

对比调试模式下的数据,看有没有不一致的地方。

4. MySQL连接中途断开

如果你的脚本执行时间较长,可能触发了MySQL的wait_timeout设置(默认是8小时,但某些服务器会改短),非调试模式下执行到一半连接断了,后面的INSERT自然失败。

排查办法:每次执行前检查连接状态

} else {
    // 先检查连接是否有效,无效则重新连接
    if (!mysql_ping()) {
        // 替换成你的数据库连接代码
        mysql_connect('你的主机', '用户名', '密码');
        mysql_select_db('你的数据库名');
    }
    $result = mysql_query($query);
    // 同样加错误捕获
    if (!$result) {
        error_log("INSERT失败:{$query} | 错误:" . mysql_error());
    }
}

5. 手动拼接SQL的隐性语法错误

你现在用的是手动拼接SQL,很容易因为字段值里的特殊字符(比如单引号、换行符)导致语法错误。比如$sector1里有个单引号,调试时显示的是'It's a lap',但实际执行时SQL会变成sector1 = 'It's a lap',直接语法错误。

长远解决办法:改用预处理语句

别再用mysql_query()了,这个函数已经被废弃了,换成mysqli或PDO的预处理语句,既安全又能避免手动拼接的错误:

// 用mysqli预处理的例子(先确保你是mysqli连接)
$stmt = $mysqli->prepare("INSERT INTO results (compId, eventId, eventSession, driverId, teamId, position, raceTime, laps, pitstops, engine, tyres, sector1, sector2, sector3, fastestLap, grid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
// 绑定参数,类型根据你的字段定义调整(i=int, s=string)
$stmt->bind_param("iisiiiiisssssisi", 
    $comp_id, 
    $eventId, 
    $eventsession, 
    $driverid, 
    $teamid, 
    $this->data['drivers']['position'][$i], 
    $racetime, 
    $this->data['drivers']['laps'][$i], 
    $this->data['drivers']['pitstops'][$i], 
    $engineId, 
    '4', 
    $sector1, 
    $sector2, 
    $sector3, 
    $this->data['drivers']['bestTime'][$i], 
    $grid
);
$stmt->execute();

第一步先做什么? 先加错误捕获,把每条SQL的执行结果和错误信息打出来,90%的情况能直接找到问题根源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:28:27