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

如何在@vercel/postgres中按ID列表查询对象?22P02错误求解

在@vercel/postgres中通过ID列表查询的问题解析

错误原因

你遇到的22P02 ERROR是PostgreSQL的无效文本表示错误,根源在于第一种写法的参数传递逻辑错误:

  • 当你用${listOTPId.join(", ")}时,实际是把ID数组拼接成了单个字符串(比如[1,2]会变成"1, 2"),最终生成的SQL语句是:
    SELECT * FROM otps WHERE id IN ('1, 2')
    
    这里PostgreSQL会把'1, 2'当成一个独立的字符串值,而你的id字段应该是数字类型(如INT/BIGINT),字符串与数字类型不匹配,直接触发22P02错误。
  • 第二种逐个传入ID的写法,@vercel/postgres的SQL模板会自动为每个参数做类型转义与匹配,生成的SQL是:
    SELECT * FROM otps WHERE id IN ($1, $2)
    
    并把listOTPId[0]和listOTPId[1]作为独立参数传入,类型完全匹配,因此能正常执行。

正确的批量查询写法

推荐两种简洁且安全的实现方式:

方式1:使用ANY操作符(更简洁)

@vercel/postgres支持直接传入数组参数,结合PostgreSQL的ANY操作符可以快速实现批量匹配:

const dataOTP = await sql<OTP>`
  SELECT *
  FROM otps
  WHERE id = ANY(${listOTPId})
`;

方式2:动态生成参数占位符

如果坚持使用IN语法,可以动态生成对应数量的参数占位符,避免手动拼接字符串:

// 生成对应数量的$1、$2...占位符
const placeholders = listOTPId.map((_, index) => `$${index + 1}`).join(', ');
const dataOTP = await sql<OTP>`
  SELECT *
  FROM otps
  WHERE id IN (${placeholders})
`(...listOTPId);

这两种方式都能保证参数类型正确,同时避免SQL注入风险。

内容的提问来源于stack exchange,提问作者DragonPi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:52:08