在 node-postgres 查询字符串中使用 UNNEST 将数组作为多行插入的语法
Syntax for using UNNEST in node-postgres query-string to insert array as multiple rows
我正在尝试插入一个简单的数字数组作为 PostgreSQL 的不同行 table。
比如我要插入:
const arr = [1.1, 2.0, 3.40, 4.5, -5];
以便 table '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()', list)
// version 2
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST(::numeric[])', list)
// version 3
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST(::[])', list)
// version 4
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST ARRAY[()]', list)
我的问题是如何使用 pg-promise 库让它工作?
非常感谢。
更新:
根据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[:csv]) \
', arr]);
原版POST:
不确定此解决方案是否理想,但以下查询产生了所需的结果:
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(, )::numeric[]) \
', [strList, delimiter]);
使用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[:csv])', [arr])
.catch(error => {
/* when in error */
});
参见 CSV Filter。
如果你的输入总是一个非空数组,那么它可以进一步简化为:
db.none('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST()', [arr])
.catch(error => {
/* when in error */
});
这是因为默认情况下非空数组被 pg-promise 格式化为 array[...]
。
看看这个:
const pgp = require('pg-promise')(/* init options */);
const s = pgp.as.format('', [arr]);
console.log(s); /*=> array[1.1,2,3.4,4.5,-5] */
我正在尝试插入一个简单的数字数组作为 PostgreSQL 的不同行 table。
比如我要插入:
const arr = [1.1, 2.0, 3.40, 4.5, -5];
以便 table '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()', list)
// version 2
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST(::numeric[])', list)
// version 3
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST(::[])', list)
// version 4
db.query('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST ARRAY[()]', list)
我的问题是如何使用 pg-promise 库让它工作?
非常感谢。
更新:
根据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[:csv]) \
', arr]);
原版POST:
不确定此解决方案是否理想,但以下查询产生了所需的结果:
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(, )::numeric[]) \
', [strList, delimiter]);
使用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[:csv])', [arr])
.catch(error => {
/* when in error */
});
参见 CSV Filter。
如果你的输入总是一个非空数组,那么它可以进一步简化为:
db.none('INSERT INTO numeric_values_list(val) SELECT * FROM UNNEST()', [arr])
.catch(error => {
/* when in error */
});
这是因为默认情况下非空数组被 pg-promise 格式化为 array[...]
。
看看这个:
const pgp = require('pg-promise')(/* init options */);
const s = pgp.as.format('', [arr]);
console.log(s); /*=> array[1.1,2,3.4,4.5,-5] */