Я использую ящик rusqlite в Rust для выполнения SQL-запросов к базе данных SQLite. У меня есть запрос, который должен фильтровать строки на основе списка значений с использованием предложения IN. Я хотел бы знать, есть ли способ передать массив или вектор в качестве параметра для предложения IN напрямую, вместо создания заполнителей для каждого элемента в списке.
Например, допустим, у меня есть следующий запрос:
SELECT * FROM articles WHERE url IN (?);
Я хотел бы передать вектор Rust в качестве параметра для ? заполнитель, например:
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! макрос, показанный в примере, не является частью крейта rusqlite. Это специальный синтаксический сахар, который я использую для упрощения процесса запроса с меньшим количеством детализации. Вопрос по-прежнему сосредоточен на передаче массива или вектора в качестве параметра для предложения IN непосредственно в rusqlite.

Кажется, нет никакого способа напрямую передать массив в IN SQLite, вам нужны заполнители, но вы можете сделать это относительно просто, используя 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(())
}
детская площадка (показывает только сгенерированные заполнители)
NB: Postgres поддерживает использование массивов, но для этого используется ANY вместо IN, например.
SELECT * FROM my_table WHERE my_column = ANY(ARRAY[1, 2, 3])
но SQLite (насколько я знаю об этом продукте) не предлагает этого.
Для SQLite есть расширение carray. А для rusqlite есть расширение rarray.
В чем разница между carray и rarray? Должен ли я использовать версию пакета Rustqlite, чтобы это работало?
Связанный: stackoverflow.com/a/69231487/450148
Carray поддерживает массив C. rarray поддерживает вектор ржавчины. Требуется только последняя версия SQLite (>= 3.20.0).
ps: не удалось увидеть изображение pastbin из текущего соединения, поэтому не могу комментировать макрос