如何在sqlx中正确使用fetch_many/execute_many执行多SQL语句?
解决sqlx批量执行多条MySQL语句的问题
问题原因
你遇到的错误是因为MySQL默认禁用了多语句执行(防止SQL注入风险),同时sqlx的execute_many设计初衷是用于批量执行参数化的单条语句,而非直接拼接多条SQL语句。
方案1:开启多语句支持并执行拼接的SQL(需注意安全)
首先在连接字符串中添加multiStatements=true参数,允许服务器执行多条语句:
use futures::StreamExt; use sqlx::Connection; #[tokio::main] async fn main() { // 添加multiStatements=true参数开启多语句支持 let mut conn = sqlx::MySqlConnection::connect("mysql://user:pass@localhost/db?multiStatements=true") .await .unwrap(); // 直接用execute执行拼接的多条语句 let result = sqlx::query(concat!( "UPDATE foo SET bar=false WHERE id=34;", "UPDATE foo SET bar=true WHERE id=43;" )) .execute(&mut conn) .await; println!("{result:?}"); }
注意:这种方式存在SQL注入风险,如果语句中包含用户输入,绝对不要使用。
方案2:用execute_many执行参数化批量更新(推荐,安全且高效)
execute_many的正确用法是传入单条参数化语句,再传入一组参数,sqlx会自动批量执行,既安全又能减少网络往返:
use futures::StreamExt; use sqlx::Connection; #[tokio::main] async fn main() { let mut conn = sqlx::MySqlConnection::connect("mysql://user:pass@localhost/db") .await .unwrap(); // 定义参数化的单条UPDATE语句 let query = sqlx::query("UPDATE foo SET bar=? WHERE id=?"); // 准备参数列表:(bar值, id) let params = vec![(false, 34), (true, 43)]; // 使用execute_many批量执行 let mut stream = query.execute_many(&mut conn, params).await.unwrap(); while let Some(result) = stream.next().await { println!("{result:?}"); } }
这种方式不需要开启多语句支持,避免了SQL注入问题,同时能达到减少网络延迟的效果,是更推荐的方案。
内容的提问来源于stack exchange,提问作者kyku
相关产品推荐
相关产品推荐

