sqlite - 为什么执行查询时Rusqlite拒绝Option类型?

标签 sqlite rust

我正在尝试将CS​​V数据插入SQLite数据库。 stripe_id是可选的,因此其类型为Option<&str>。其他所有字段均为&str。当我使用conn.execute插入值时,除了stripe_id之外,它们均正确插入,这引发了错误,提示它期望使用&str而不是Option

我已经搜索了文档,并且Option<T>实现了ToSQL,当我尝试用包含Option值的Rusqlite示例替换代码时,该示例代码也会引发相同的错误。

相关的结构和查询代码段:

struct Merchant<'a> {
    name: &'a str,
    billing_portal: &'a str,
    billing_period: &'a str,
    stripe_id: Option<&'a str>,
}

conn.execute(
    "INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
     values (?, ?, ?, ?)",
     &[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
).expect("Error inserting merchant into database");

错误:

error[E0308]: mismatched types
  --> src/main.rs:38:75
   |
38 |              &[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
   |                                                                           ^^^^^^^^^^^^^^^^ expected `&str`, found enum `std::option::Option`
   |
   = note: expected reference `&&str`
              found reference `&std::option::Option<&str>`

以及完整的代码:

extern crate csv;
extern crate rusqlite;

use rusqlite::{Connection, Result};

#[derive(Debug)]
struct Merchant<'a> {
    name: &'a str,
    billing_portal: &'a str,
    billing_period: &'a str,
    stripe_id: Option<&'a str>,
}

fn main() -> Result<()> {
    let conn = Connection::open("data.sqlite")?;

    let mut reader = csv::ReaderBuilder::new()
                                        .has_headers(false)
                                        .from_path("merchants.csv")
                                        .expect("Failed to read csv");
    for record in reader.records() {
        let record = record.unwrap();
        let merch = Merchant {
            name: &record[0],
            billing_portal: &record[3],
            billing_period: &record[4],
            stripe_id: (match &record[5] {
                x if x == "" => None,
                x            => Some(x)
            }),
        };
        println!("{:?}", &merch);

        conn.execute(
            "INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
             values (?, ?, ?, ?)",
             &[&merch.name, &merch.billing_portal, &merch.billing_period, &merch.stripe_id]
        ).expect("Error inserting merchant into database");

    }

    Ok(())
}

最佳答案

使用 rusqlite::params 宏可以解决此问题:

use rusqlite::{params, Connection, Result};

fn main() -> Result<()> {
    // ...

    for record in reader.records() {
        // ...

        conn.execute(
            "INSERT INTO merchants (name, billing_portal, billing_period, stripe_id)
             values (?, ?, ?, ?)",
            params![
                &merch.name,
                &merch.billing_portal,
                &merch.billing_period,
                &merch.stripe_id,
            ],
        )
        .expect("Error inserting merchant into database");
    }

    Ok(())
}

关于sqlite - 为什么执行查询时Rusqlite拒绝Option类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59900003/

相关文章:

generics - 如果我在函数内部创建引用,如何将泛型类型与需要生命周期参数的特征绑定(bind)?

c - SQLite3 : non-ascii unicode chars' update not working?

iphone - 如何在 sqlite3 中向整个列插入相同的值?

android - 查询返回一个 toString() 值?

java - 将 TimePicker 数据保存在 sqlite 数据库中

rust - 返回引用当前函数拥有的数据的值

rust - 使用 tar 箱解压文件时没有方法 'entries_mut'?

sqlite - 如何在 SQLite 中获取分层树路径?

rust - 如何在下载过程中解压缩和解压 tar.gz 存档?

types - 在火柴臂中创建闭包