如何在Diesel的sql_query中一次性绑定多个未知数量的参数?
问题原因
你调用的collect_binds是Diesel的内部低阶API,它要求传入对应数据库后端实现了BindCollector trait的实例,而非你自定义的Vec<i64>,普通业务开发完全不需要调用该方法。
你不需要手动拼接SQL占位符再自己管理参数绑定,Diesel本身提供了更简便的实现方式,以下是两种可行方案:
方案一:使用Diesel DSL原生查询(推荐)
直接用Diesel提供的查询构造器,不需要手写任何Raw SQL,自动处理动态长度的IN条件参数绑定:
use diesel::prelude::*; // 导入你的项目中自动生成的preferences表schema use crate::schema::preferences; let org_id = 10; let team_ids = get_needed_teams_id(); let preferences: Vec<Preferences> = preferences::table .filter(preferences::org_id.eq(org_id)) .filter(preferences::team_id.eq_any(team_ids)) .order((preferences::user_id.asc(), preferences::team_id.asc())) .load(&mut db_connection)?; // db_connection为你的PostgreSQL连接实例
注意:该方案要求
Preferences结构体派生Queryabletrait,且你的项目中已经正确生成了schema文件。
方案二:使用Raw SQL动态绑定参数
如果你确实需要手写Raw SQL,可以直接迭代调用bind方法,不需要固定链式调用:
use diesel::prelude::*; use diesel::sql_query; use diesel::sql_types::Int8; let org_id = 10; let team_ids = get_needed_teams_id(); // 生成IN子句的占位符,格式为$2, $3, $n let placeholder_str = (2..=team_ids.len() + 1) .map(|idx| format!("${idx}")) .collect::<Vec<_>>() .join(", "); let raw_sql = format!( "SELECT * FROM preferences WHERE org_id = $1 AND team_id IN ({placeholder_str}) ORDER BY user_id ASC, team_id ASC" ); // 动态绑定参数 let mut query = sql_query(raw_sql).bind::<Int8, _>(org_id); for team_id in team_ids { query = query.bind::<Int8, _>(team_id); } // 执行查询获取结果 let preferences: Vec<Preferences> = query.load(&mut db_connection)?;
注意:该方案要求
Preferences结构体派生QueryableByNametrait,用于Raw SQL的字段映射。
内容的提问来源于stack exchange,提问作者omar
相关产品推荐
相关产品推荐

