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

如何在pg-promise复杂SQL查询中生成无额外引号的VALUES列表?

用pg-promise构建复杂SQL查询时避免VALUES列表被添加额外引号

问题场景

我尝试用pg-promise构建嵌套SQL查询,SQL模板如下:

WITH insert_and_return AS
  (
    INSERT INTO myTable
      (param_01, param_02, param_03, param_id)
    VALUES
      (${param_01}, ${param_02}, ${param_03}, uuid_generate_v4())  
    RETURNING
      param_id
  )

named_data (name, values) AS
  (
    VALUES
      ${pairs}
  )

INSERT INTO anotherTable
  SELECT ir.param_id, nd.name, nd.values
  FROM insert_and_return AS ir, named_data AS nd;

执行代码中,我用pgp.helpers.values生成了VALUES需要的括号化值序列:

const data = { one: ['one'], two: ['two']};
const data_pairs = [ {key: 'one', value: ['one']}, {key: 'two', value: ['two']} ];

const pairs = pgp.helpers.values(data_pairs, ['key', 'value']);
// 预期输出:('one',array['one']),('two',array['two'])

query = pgp.as.format(sqlFile, { param_01, param_02, param_03, pairs })
await db.none(query)

但实际生成的SQL里,${pairs}被自动添加了额外引号,导致语法错误。

解决方案

pgp.as.format默认会对字符串参数做转义并添加引号,而pgp.helpers.values已经生成了合法的SQL片段,不需要额外处理,可通过以下两种方式解决:

方法1:修改SQL模板占位符

将SQL中的${pairs}改为${pairs:raw},明确告知pg-promise直接插入文本,不做转义:

named_data (name, values) AS
  (
    VALUES
      ${pairs:raw}
  )

方法2:传参时标记为raw文本

调用pgp.as.format时,用pgp.as.format.raw()包装生成的pairs值:

query = pgp.as.format(sqlFile, { 
  param_01, 
  param_02, 
  param_03, 
  pairs: pgp.as.format.raw(pairs) 
})

两种方法都能让pairs部分保持('one',array['one']),('two',array['two'])的正确格式,不会被添加额外引号。

内容的提问来源于stack exchange,提问作者M.Holmes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:25:17