如何在@vercel/postgres中按ID列表查询对象?22P02错误求解
在@vercel/postgres中通过ID列表查询的问题解析
错误原因
你遇到的22P02 ERROR是PostgreSQL的无效文本表示错误,根源在于第一种写法的参数传递逻辑错误:
- 当你用
${listOTPId.join(", ")}时,实际是把ID数组拼接成了单个字符串(比如[1,2]会变成"1, 2"),最终生成的SQL语句是:
这里PostgreSQL会把SELECT * FROM otps WHERE id IN ('1, 2')'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
相关产品推荐
相关产品推荐

