问题描述
以下代码无法编译:
55 | (":dataset_id",&dataset_id),| ^^^^^^^^^^^ expected `u32`,found `i32`
pub fn save(&mut self,annotations: Vec<Record>,dataset_id: i32) -> Result<(),Error> {
let mut tx = self.conn.transaction()?;
for record in records {
let json: String = record();
let sql: &str =
"INSERT INTO records (record_id,dataset_id,value)
VALUES (:record_id,:dataset_id,:value)";
let mut statement = tx.prepare(sql)?;
statement.execute(&[
(":record_id",&record.id),(":dataset_id",(":value","hello world")]);
};
tx.commit()?;
Ok(())
}
如果我从我的 sql 语句中删除 dataset_id 并注释掉该行:(":dataset_id",
然后它无法编译:
56 | (":value",&"hello".to_string()),| ^^^^^^^^^^^^^^^^^^^^ expected `u32`,found struct `std::string::String`
解决方法
execute
的参数是 P: Params
,即“任何实现 Params
的类型”。 Rust 编译器不会猜测什么你想要的特定类型,然后相应地处理参数。相反,它只会自行解析参数的类型,然后查看它是否实现了 Params
。
这是你的论点:
&[(":record_id",&record.id),(":dataset_id",&dataset_id),(":value","hello world")]
就其本身而言,类型是什么?它是对包含三个元组的数组文字的引用:(&str,&u32)
、(&str,&i32)
和 (&str,&str)
。
由于缺少任何进一步的信息,编译器猜测第一个元素是规范元素,因此尝试相应地转换其他元素。因此,您会收到“无法将 &i32
转换为 &u32
”错误。
然而,您需要的是一个 (&str,&dyn ToSql)
元组数组。
所以你可以做两件事之一。
首先,将第一个参数值显式转换为正确的类型:
&[(":record_id",&record.id as &dyn ToSql),"hello world")]
或者第二个,使用 named_params!
提供的 rusqlite
宏,可以说它更漂亮:
statement.execute(named_params!{
":record_id": record.id,":dataset_id": dataset_id,":value": "hello world",});