如何在pg-promise的multi多查询中追踪结果所属的原始查询?
解决方法
你的核心问题是原代码的map回调没有返回处理后的查询对象,且对pgp.helpers.concat的用法有误(它需要的是包含query和values的对象数组,而非纯字符串数组)。以下是两种可行的实现方式:
方法一:包装子查询并保留参数绑定
直接将每个用户查询包装为子查询,添加追踪列后,生成符合pg-promise要求的查询对象数组,再传入db.multi执行:
const queryArray = [ { query: "SELECT * FROM credentials_entities WHERE type = $1", values: ['public'] }, { query: "SELECT * FROM credentials_entities WHERE type = $1", values: ['shared'] } ]; // 包装每个查询,添加query_index追踪列 const wrappedQueries = queryArray.map((item, index) => { return { // 用子查询包装原查询,添加追踪列 query: `SELECT ${index} AS query_index, * FROM (${item.query}) AS sub_query`, values: item.values // 保留原参数绑定,避免SQL注入 }; }); // 执行多个查询 const result = await db.multi(wrappedQueries);
每个查询结果都会包含query_index列,对应原queryArray中的索引位置,可直接通过该值判断结果来源。
方法二:修正CTE实现(沿用你的思路)
如果你坚持使用CTE,只需修正map的返回逻辑,确保生成正确的查询对象:
const wrappedQueries = queryArray.map((item, index) => { return { query: ` WITH cte_${index} AS (${item.query}) SELECT ${index} AS query_index, * FROM cte_${index} `, values: item.values }; }); const result = await db.multi(wrappedQueries);
关键注意事项
- 必须确保
map回调有返回值:原代码中map未返回处理后的对象,导致dynamicQueries全为undefined,这是最直接的错误。 - 保留参数绑定:始终传递原查询的
values,既保证参数生效,又避免SQL注入风险。 db.multi支持直接传入查询对象数组:无需强制使用pgp.helpers.concat,除非你需要手动控制查询拼接逻辑。
内容的提问来源于stack exchange,提问作者inoabrian
相关产品推荐
相关产品推荐

