【问题标题】:Syntax for using UNNEST in node-postgres query-string to insert array as multiple rows在 node-postgres 查询字符串中使用 UNNEST 将数组插入为多行的语法
【发布时间】:2019-09-07 00:26:18
【问题描述】:

我正在尝试它插入一个简单的数字数组作为 PostgreSQL 表的不同行。

比如我要插入:

const arr = [1.1, 2.0, 3.40, 4.5, -5];

以便表“numeric_values_list”填充到:

id | val 
--------
1  | 1.1
2  | 2.0
3  | 3.40
4  | 4.5
5  | -5.6

使用 psql 终端,我可以得到这个查询以产生所需的结果:

INSERT INTO numeric_values_list(val)
SELECT * FROM UNNEST (ARRAY[1.1, 2.0, 3.40, 4.5, -5]);

但是,我无法找出将产生相同结果的 postgres-pg 查询字符串的正确语法。以下对我不起作用:

  const list = [1.1, 2.0, 3.40, 4.5, -5];

  // version 1
  db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST($1)', list)

  // version 2
  db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST($1::numeric[])', list)

  // version 3
  db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST($1::[])', list)

  // version 4
  db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST ARRAY[($1)]', list)

我的问题是如何使用 pg-promise 库让它工作?
非常感谢。

【问题讨论】:

  • 使用pg-promise,您可以简单地使用csv 过滤器,它会起作用;)
  • 哦,真漂亮。如果您想将评论移至答案,我会检查它是否正确。

标签: postgresql node-postgres


【解决方案1】:

这在使用pg-promise时会简单得多:

const arr = [1.1, 2.0, 3.40, 4.5, -5];

db.none('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST(ARRAY[$1:csv])', [arr])
  .catch(error => {
      /* when in error */
  });

CSV Filter

如果你的输入总是一个非空数组,那么它可以进一步简化为:

db.none('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST($1)', [arr])
  .catch(error => {
      /* when in error */
  });

这是因为默认情况下,非空数组由pg-promise 格式化为array[...]

看看这个:

const pgp = require('pg-promise')(/* init options */);

const s = pgp.as.format('$1', [arr]);

console.log(s); /*=> array[1.1,2,3.4,4.5,-5] */

【讨论】:

    【解决方案2】:

    更新:

    使用 vitaly-t 的建议,以下代码完全符合我的要求:

    const arr = [1.1, 2.0, 3.40, 4.5, -5];
    
    ...
    
    db.query('                             \
      INSERT INTO numeric_values_list(val) \
      SELECT * FROM UNNEST(ARRAY[$1:csv])  \
    ', arr]);
    

    原帖:

    不确定此解决方案是否理想,但以下查询产生了所需的结果:

    const arr = [1.1, 2.0, 3.40, 4.5, -5];
    
    const strList = String(arr);
    const delimiter = ',';
    
    ...
    
    db.query('                                                 \
      INSERT INTO numeric_values_list(val)                     \
      SELECT * FROM UNNEST(STRING_TO_ARRAY($1, $2)::numeric[]) \
    ', [strList, delimiter]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-27
      • 2022-06-13
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      相关资源
      最近更新 更多