#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(&params)?).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)