rust 使用rusqlite crate,我可以传递一个数组作为包含'IN'的子句的参数吗?

1cosmwyk  于 2023-05-07  发布在  SQLite
关注(0)|答案(2)|浏览(195)

我在Rust中使用rusqlite crate在SQLite数据库上执行SQL查询。我有一个查询,需要使用IN子句根据值列表过滤行。我想知道是否有一种方法可以直接将数组或向量作为IN子句的参数传递,而不是为列表中的每个元素创建占位符。
例如,假设我有以下查询:

SELECT * FROM articles WHERE url IN (?);

我想传递一个Rust vector作为?占位符,如下所示:

let urls: Vec<String> = vec![
    "example1.com".to_string(),
    "example2.com".to_string(),
];

let result: Vec<String> = easy_query!(query, params![urls], Vec<String>)?;

有没有更直接的方法来实现这一点,而不必为数组或向量中的每个元素创建占位符,并将它们作为单独的参数传递?
提前感谢您的帮助。

  • 注意:示例中显示的easy_query! macro不是rusqlite crate的一部分。它是一种自定义的语法糖,我使用它来简化查询过程,减少冗长。问题仍然集中在直接在rusqlite中传递数组或向量作为IN子句的参数。*
ozxc1zmp

ozxc1zmp1#

似乎没有任何方法可以直接将数组传递到SQLite的IN中,您确实需要占位符,但您可以通过使用std::iter::repeat()collect::<Vec<_>>().join(",")来使其相对简单:

use rusqlite::{params, Connection};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let conn = Connection::open_in_memory()?;

    let names = vec!["Alice", "Bob", "Charlie"];
    let placeholders: String = std::iter::repeat("?").take(names.len()).collect::<Vec<_>>().join(",");

    let ids: Vec<i64> = conn
        .prepare(&format!("SELECT id FROM users WHERE name IN ({})", placeholders))
        .unwrap()
        .query_map(names, |row| row.get(0))?
        .map(|id| id.unwrap())
        .collect();

    println!("IDs: {:?}", ids);

    Ok(())
}

playground(仅显示生成的占位符)
nb:Postgres确实支持数组的使用,但为此使用了ANY而不是IN。

SELECT * FROM my_table WHERE my_column = ANY(ARRAY[1, 2, 3])

但SQLite(就我对该产品的有限了解而言)并不提供它。

qvk1mo1f

qvk1mo1f2#

对于SQLite,有carray扩展。对于rusqlite,有rarray扩展。

相关问题