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

使用Erlang的mysql-otp驱动批量插入多行数据的方法问询

解决mysql-otp批量插入多行数据的问题

嘿,我完全懂你的困扰——mysql-otp的文档确实没把批量插入的细节讲透,你试的那种嵌套元组列表的写法确实走不通,因为驱动明确要求Params是扁平的term列表,而不是嵌套结构。不过别担心,有两种实用的方式可以实现批量插入:

方法一:构造多行VALUES的单条SQL语句

这是效率最高的方式,适合插入大量数据。核心思路是把所有行的参数扁平化成一个列表,同时在SQL里生成对应的多个(?, ?)子句。你可以写个小工具函数来自动拼接SQL和处理参数:

batch_insert(Pid, Table, Columns, Rows) ->
    % 生成每个行对应的(?, ?)子句
    ValueClause = "(" ++ string:join(lists:duplicate(length(Columns), "?"), ", ") ++ ")",
    % 把所有子句用逗号连接
    ValueClauses = string:join(lists:duplicate(length(Rows), ValueClause), ", "),
    % 拼接完整的INSERT语句
    Sql = io_lib:format("INSERT INTO ~s (~s) VALUES ~s", [Table, string:join(Columns, ", "), ValueClauses]),
    % 把嵌套的元组列表扁平化为一维参数列表
    FlatParams = lists:flatten(Rows),
    % 执行查询
    mysql:query(Pid, Sql, FlatParams).

% 使用示例
ok = batch_insert(Pid, "mytable", ["id", "bar"], [{1, 42}, {2, 36}, {3, 12}]).

这个函数会自动生成类似INSERT INTO mytable (id, bar) VALUES (?, ?), (?, ?), (?, ?)的SQL,参数则是[1,42,2,36,3,12],完全符合驱动的参数要求。

方法二:用事务批量执行单行插入

如果插入的行数不多,这种方式更直观,不需要拼接复杂的SQL,还能保证原子性(要么全成功,要么全回滚):

batch_insert_with_transaction(Pid, Rows) ->
    % 开启事务
    ok = mysql:query(Pid, "START TRANSACTION"),
    try
        % 遍历每一行执行插入
        lists:foreach(fun({Id, Bar}) ->
            ok = mysql:query(Pid, "INSERT INTO mytable (id, bar) VALUES (?, ?)", [Id, Bar])
        end, Rows),
        % 提交事务
        ok = mysql:query(Pid, "COMMIT")
    catch
        % 出错时回滚事务
        _:_ ->
            ok = mysql:query(Pid, "ROLLBACK"),
            error(batch_insert_failed)
    end.

% 使用示例
ok = batch_insert_with_transaction(Pid, [{1, 42}, {2, 36}, {3, 12}]).

这种方式的缺点是每一行都要发一次请求,数据量很大时性能不如第一种方法,但胜在代码简单易懂,适合小批量场景。

为什么你原来的写法不行?

你试的[(1,42),(2,36),(3,12)]是一个包含三个元组的列表,而驱动期望的是和SQL占位符数量完全匹配的扁平列表。比如你的SQL里有2个占位符,但你传了3个参数(每个元组算一个),驱动会因为参数数量不匹配而报错,所以这种写法确实不可行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:25:26