如何用Dapper在MySQL中通过存储过程实现批量插入?
MySQL 批量插入多行的存储过程替代方案
1. 用 JSON 参数传递批量数据(MySQL 5.7+ 推荐)
利用 MySQL 原生的 JSON 解析能力,把多行数据打包成 JSON 字符串传入存储过程,再解析后插入。
修改后的存储过程:
CREATE PROCEDURE InsertMultiple( IN data JSON ) BEGIN INSERT INTO Foo (Id, Name) SELECT j.id, j.name FROM JSON_TABLE( data, '$[*]' COLUMNS( id INT PATH '$.id', name VARCHAR(50) PATH '$.name' ) ) AS j; END$$
Dapper 调用方式:
把数据序列化成 JSON 字符串作为参数传入:
// 用 System.Text.Json 或 Newtonsoft.Json 序列化 var jsonData = JsonSerializer.Serialize(items); connection.Execute("InsertMultiple", new { data = jsonData }, commandType: CommandType.StoredProcedure);
2. 分隔符拼接字符串参数(兼容低版本 MySQL)
如果你的 MySQL 版本不支持 JSON,可以把多组 id 和 name 分别用分隔符拼接成字符串,在存储过程里拆分后插入。
修改后的存储过程:
CREATE PROCEDURE InsertMultiple( IN ids VARCHAR(1000), -- 格式示例:"1,2,3" IN names VARCHAR(5000) -- 格式示例:"Alice,Bob,Charlie" ) BEGIN INSERT INTO Foo (Id, Name) SELECT CAST(SUBSTRING_INDEX(SUBSTRING_INDEX(ids, ',', n.n), ',', -1) AS INT) AS id, SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', n.n), ',', -1) AS name FROM (SELECT 1 n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5) n WHERE n.n <= LENGTH(ids) - LENGTH(REPLACE(ids, ',', '')) + 1; END$$
注意:示例中的数字表(
SELECT 1 UNION ALL...)需要根据你的最大插入行数调整;MySQL 8.0+ 可以用递归 CTE 生成更灵活的数字序列。
Dapper 调用方式:
var ids = string.Join(",", items.Select(r => r.Id)); var names = string.Join(",", items.Select(r => r.Name)); connection.Execute("InsertMultiple", new { ids, names }, commandType: CommandType.StoredProcedure);
3. Dapper 批量循环调用原存储过程(无需修改存储过程)
如果不想改动现有存储过程,可以直接让 Dapper 帮你循环调用,它会复用连接,比手动写循环效率更高:
// 直接传入参数集合,Dapper 自动循环执行存储过程 connection.Execute( "InsertMultiple", items.Select(r => new { id = r.Id, name = r.Name }), commandType: CommandType.StoredProcedure );
4. 临时表中转方案
先通过 Dapper 把数据插入临时表,再调用存储过程从临时表同步到目标表:
存储过程修改:
CREATE PROCEDURE InsertMultipleFromTemp() BEGIN INSERT INTO Foo (Id, Name) SELECT Id, Name FROM #TempFoo; DROP TABLE IF EXISTS #TempFoo; END$$
Dapper 调用流程:
// 先创建临时表并批量插入数据 connection.Execute("CREATE TEMPORARY TABLE #TempFoo (Id INT, Name VARCHAR(50))"); connection.Execute("INSERT INTO #TempFoo (Id, Name) VALUES (@id, @name)", items); // 调用存储过程完成最终插入 connection.Execute("InsertMultipleFromTemp", commandType: CommandType.StoredProcedure);
内容的提问来源于stack exchange,提问作者andrea_k
相关产品推荐
相关产品推荐

