#rusqlite
1. WHERE句とパラメータをそれぞれ動的な[[ベクター]]で用意する
2. 引数が指定された(Some)の場合に限り、1にそれぞれ追加
- [[ライフタイム]]の関係により`params`に指定する値はif文の外側で作成が必要
3. WHERE句はフォーマットの[[SQL]]にはめ込む
- 引数は一切関与しないため[[SQLインジェクション]]の心配はない
- この時点だとパラメータは[[プレースホルダー]]になっている
4. [[プレースホルダー]]に`query_named`でパラメータを設定する
```rust:Optionが指定されたパラメータだけWHERE句に追加
pub fn select_humans_by(
conn: &mut Connection,
ids: Option<Vec<String>>,
name_prefix: Option<String>,
) -> serde_rusqlite::Result<Vec<Human>> {
let mut where_clause: Vec<String> = vec![];
let mut params: Vec<(&str, &dyn ToSql)> = vec![];
let ids = &Rc::new(
ids
.unwrap_or_default()
.into_iter()
.map(Value::from)
.collect_vec(),
);
if !ids.is_empty() {
where_clause.push("id in rarray(:ids)".to_string());
params.push((":ids", &ids));
}
let name_prefix_query = name_prefix.map(|x| format!("{}%", x));
if let Some(p) = &name_prefix {
where_clause.push("name like :name_prefix".to_string());
params.push((":name_prefix", p));
}
let sql = format!(
r#"
SELECT id, name
FROM humans
WHERE {}
ORDER BY id
"#,
where_clause.join(" AND ")
);
let mut stmt = conn.prepare(sql.as_str())?;
let result = from_rows(stmt.query_named(¶ms)?).collect();
result
}
```
## 参考
- [Rocket, rusqlite, dynamic parameters & lifetimes \- help \- The Rust Programming Language Forum](https://users.rust-lang.org/t/rocket-rusqlite-dynamic-parameters-lifetimes/38268)