You need to enable JavaScript to run this app. Laravel中使用MySQL变量执行原生查询报1064语法错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中使用MySQL变量执行原生查询报1064语法错误如何解决

你遇到的语法报错是因为Laravel默认禁用了PDO的多语句执行能力,你在单个DB::statement调用中传入了两条SET语句,相当于一次执行多条SQL,不符合默认的执行规则,就会抛出语法错误。
你之前尝试把SET和查询放在同一段SQL里报错也是同样的原因。


方案1:拆分SET语句单独执行(最推荐,无额外安全风险)

把两条SET语句分开,每条单独调用一次DB::statement执行,不需要修改任何连接配置,变量会在当前数据库连接的生命周期内生效,后续查询可以正常调用:

// 单独设置每个SQL变量
DB::statement('SET @lon = ?', [$longitude]);
DB::statement('SET @lat = ?', [$latitude]);

// 后续查询逻辑保持不变,不需要套DB::raw,原生查询方法本身支持直接传SQL和参数绑定
$places = DB::select(
    "
    SELECT id
    FROM places
    WHERE
        position = POINT(@lon, @lat)
        AND language = ?
        AND LOWER(name) LIKE LOWER(CONCAT(?, '%'))
    ORDER BY distance
    LIMIT 10;
    ",
    [$language, $name]
);

方案2:临时开启多语句执行(适合多语句场景,注意防范注入风险)

如果需要执行的SET语句数量较多,拆分执行太繁琐,可以临时开启当前连接的多语句执行权限,用完后建议立刻关闭,降低SQL注入风险:

// 临时开启多语句支持
DB::connection()->getPdo()->setAttribute(\PDO::MYSQL_ATTR_MULTI_STATEMENTS, true);

// 一次性执行多条SET语句
DB::statement(
    "
    SET @lon = ?;
    SET @lat = ?;
    ",
    [$longitude, $latitude]
);

// 执行完成后关闭多语句支持
DB::connection()->getPdo()->setAttribute(\PDO::MYSQL_ATTR_MULTI_STATEMENTS, false);

// 后续查询逻辑不变
$places = DB::select(
    "
    SELECT id
    FROM places
    WHERE
        position = POINT(@lon, @lat)
        AND language = ?
        AND LOWER(name) LIKE LOWER(CONCAT(?, '%'))
    ORDER BY distance
    LIMIT 10;
    ",
    [$language, $name]
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 06:15:10