You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PostgreSQL-Rust中正确使用NOT IN语句?——基于deadpool-postgres与actix-web的报错排查

解决PostgreSQL中NOT IN语句的参数化问题

你遇到的问题其实是PostgreSQL对NOT IN语法的要求和参数化查询的适配问题——直接把Vec作为参数传给NOT IN $2是行不通的,因为PostgreSQL期望NOT IN后面跟的是括号包裹的多个值,而不是单个数组/列表参数。下面给你两种靠谱的解决思路:

方法一:使用ANY/ALL操作符(推荐)

PostgreSQL支持用ANY操作符配合数组来实现类似IN的逻辑,而deadpool-postgres可以自动把Rust的Vec转换成PostgreSQL的数组类型。你可以把SQL语句改成下面这样:

let client: Client = db_pool.get().await.unwrap();
let mut interface_ids_to_keep: Vec<i32> = Vec::new();
// 添加需要保留的ID到interface_ids_to_keep中

// 使用 != ALL($2) 替代 NOT IN $2
client.execute(
    "DELETE FROM interface WHERE host_id = $1 AND interface_id != ALL($2)",
    &[&host.host_id, &interface_ids_to_keep]
).await.unwrap();

或者也可以写成NOT (interface_id = ANY($2)),效果是完全一致的:

client.execute(
    "DELETE FROM interface WHERE host_id = $1 AND NOT (interface_id = ANY($2))",
    &[&host.host_id, &interface_ids_to_keep]
).await.unwrap();

这种方法的好处是不需要手动处理参数数量,代码简洁且安全,完全符合参数化查询的要求,是最推荐的方案。

方法二:动态生成参数占位符

如果你更倾向于使用原生的NOT IN语法,可以动态生成对应数量的参数占位符,比如当interface_ids_to_keep有3个元素时,生成($2, $3, $4),然后把所有参数合并到参数列表中:

let client: Client = db_pool.get().await.unwrap();
let mut interface_ids_to_keep: Vec<i32> = Vec::new();
// 添加需要保留的ID到interface_ids_to_keep中

// 生成占位符,比如$2, $3, $4
let placeholders: Vec<String> = (2..=interface_ids_to_keep.len()+1)
    .map(|n| format!("${n}"))
    .collect();
let placeholder_str = format!("({})", placeholders.join(", "));

// 拼接SQL语句
let sql = format!(
    "DELETE FROM interface WHERE host_id = $1 AND interface_id NOT IN {}",
    placeholder_str
);

// 构造参数列表:先放host_id,再放所有要保留的ID
let mut params: Vec<&dyn ToSql> = vec![&host.host_id];
params.extend(interface_ids_to_keep.iter().map(|id| id as &dyn ToSql));

// 执行查询
client.execute(&sql, &params).await.unwrap();

这种方法需要手动处理参数占位符的生成,代码相对繁琐,但更贴近原生的NOT IN语法。

为什么原来的代码会报错?

PostgreSQL的NOT IN语法严格要求后面跟(值1, 值2, ...)的形式,而你直接传递$2时,PostgreSQL会把它当成单个值,而不是一组值,所以会触发syntax error at or near "$2"的错误——它根本不认识这种写法。

内容的提问来源于stack exchange,提问作者Ace of Spade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:37:27