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

为什么Laravel中执行SOURCE命令报MySQL 1064错误但命令行运行正常?

问题原因

SOURCE 不是MySQL服务端支持的SQL语法,它是MySQL官方命令行客户端专属的内置命令,仅在你直接使用mysql命令行交互/导入时才会被识别。通过Laravel DB门面、PDO这类直接向MySQL服务端发送SQL语句的接口执行SOURCE,服务端完全无法解析,自然会抛出1064语法错误。

另外你代码里还有两个非核心问题:

  • 定义$snapshot变量时末尾多带了多余的分号
  • DROP、CREATE DATABASE属于DDL语句,会自动触发隐式提交,外层包裹的事务完全不会生效,无法起到回滚作用
解决方案

以下两种方案都可以在Artisan命令中直接实现需求:

方案1:调用Shell执行MySQL导入(最稳妥,和命令行执行效果完全一致)

直接在PHP中执行你原本命令行的导入逻辑即可,Homestead环境下cli运行的Artisan命令默认有对应权限:

$dbUser = 'homestead';
$dbPass = 'secret';
$dbName = 'homestead';
$snapshotPath = '/home/vagrant/Data/local-db-snapshot.sql';

// 先删库建库,再直接导入快照文件
exec("mysql -h localhost -u {$dbUser} -p{$dbPass} -e 'DROP DATABASE IF EXISTS {$dbName}; CREATE DATABASE {$dbName};' && mysql -h localhost -u {$dbUser} -p{$dbPass} {$dbName} < {$snapshotPath}", $output, $returnVar);

// 判断执行结果
if ($returnVar !== 0) {
    $this->error('数据库恢复失败:' . implode("\n", $output));
    return;
}
$this->info('数据库恢复成功');

方案2:读取SQL文件内容直接执行(不依赖Shell调用)

如果你的场景不允许执行Shell命令,可以读取快照文件的SQL内容,用Laravel的多语句执行接口运行:

$db = 'homestead';
$snapshotPath = '/home/vagrant/Data/local-db-snapshot.sql';

// 删库建库切换库
DB::statement('DROP DATABASE IF EXISTS ' . $db);
DB::statement('CREATE DATABASE ' . $db);
DB::statement('USE ' . $db);

// 读取SQL文件内容直接执行
$sql = file_get_contents($snapshotPath);
DB::unprepared($sql);

注意如果你的SQL文件包含存储过程、触发器、特殊注释等复杂语法,优先使用方案1,避免语法解析边界问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:27:02