Javascript 如何正确地将多行插入带有节点postgres的PG中?

Javascript 如何正确地将多行插入带有节点postgres的PG中?,javascript,sql,node.js,postgresql,node-postgres,Javascript,Sql,Node.js,Postgresql,Node Postgres,可以按如下方式插入一行: client.query("insert into tableName (name, email) values ($1, $2) ", ['john', 'john@gmail.com'], callBack) 这种方法会自动注释掉任何特殊字符 如何一次插入多行 我需要实施以下措施: "insert into tableName (name, email) values ('john', 'john@gmail.com'), ('jane', 'jane@gmail

可以按如下方式插入一行:

client.query("insert into tableName (name, email) values ($1, $2) ", ['john', 'john@gmail.com'], callBack)
这种方法会自动注释掉任何特殊字符

如何一次插入多行

我需要实施以下措施:

"insert into tableName (name, email) values ('john', 'john@gmail.com'), ('jane', 'jane@gmail.com')"
我可以使用js字符串操作符手动编译这样的行,但是我需要以某种方式添加特殊字符

client.query("insert into tableName (name, email) values ($1, $2),($3, $4) ", ['john', 'john@gmail.com','john', 'john@gmail.com'], callBack)
没用吗? 此外,您还可以手动生成查询字符串:

insert into tableName (name, email) values (" +var1 + "," + var2 + "),(" +var3 + ", " +var4+ ") "
如果您在这里阅读,您可以看到相同的实现。

本文如下:从库及其建议的方法:

// Concatenates an array of objects or arrays of values, according to the template,
// to use with insert queries. Can be used either as a class type or as a function.
//
// template = formatting template string
// data = array of either objects or arrays of values
function Inserts(template, data) {
    if (!(this instanceof Inserts)) {
        return new Inserts(template, data);
    }
    this._rawDBType = true;
    this.formatDBType = function () {
        return data.map(d=>'(' + pgp.as.format(template, d) + ')').join(',');
    };
}
使用它的一个示例,与您的情况完全相同:

var users = [['John', 23], ['Mike', 30], ['David', 18]];

db.none('INSERT INTO Users(name, age) VALUES $1', Inserts('$1, $2', users))
    .then(data=> {
        // OK, all records have been inserted
    })
    .catch(error=> {
        // Error, no records inserted
    });
它还可以处理一组对象:

var users = [{name: 'John', age: 23}, {name: 'Mike', age: 30}, {name: 'David', age: 18}];

db.none('INSERT INTO Users(name, age) VALUES $1', Inserts('${name}, ${age}', users))
    .then(data=> {
        // OK, all records have been inserted
    })
    .catch(error=> {
        // Error, no records inserted
    });
更新-1

有关通过单个
INSERT
查询实现的高性能方法,请参阅

更新-2


这里的信息现在已经很旧了,请参阅最新的语法。以前是
\u rawDBType
的现在是
rawDBType
formatDBType
被重命名为
toPostgres
,另一种使用PostgreSQL json函数的方式:

client.query('INSERT INTO table (columns) ' +
  'SELECT m.* FROM json_populate_recordset(null::your_custom_type, $1) AS m',
  [JSON.stringify(your_json_object_array)], function(err, result) {
    if (err) {
      console.log(err);
    } else {
      console.log(result);
    }
});
像下面这样使用

var format = require('pg-format');

var values = [
  [7, 'john22', 'john22@gmail.com', '9999999922'], 
  [6, 'testvk', 'testvk@gmail.com', '88888888888']
];
client.query(format('INSERT INTO users (id, name, email, phone) VALUES %L', values),[], (err, result)=>{
  console.log(err);
  console.log(result);
});

您必须动态生成查询。尽管这是可能的,但这是有风险的,如果您做得不对,很容易导致SQL注入漏洞。查询中的参数索引和传递的参数之间也很容易出现off-by-one错误

话虽如此,这里有一个示例,说明了如何编写此代码,假设您有一个用户数组,看起来像
{name:string,email:string}

client.query(
  `INSERT INTO table_name (name, email) VALUES ${users.map(() => `(?, ?)`).join(',')}`,
  users.reduce((params, u) => params.concat([u.name, u.email]), []),
  callBack,
)
另一种方法是使用库,如(我写的):


@数据库要求使用
sql
标记查询,并使用该标记确保您传递的任何用户数据始终自动转义。这还可以让您内联编写参数,我认为这会使代码更具可读性。

有什么原因不能简单地执行INSERT两次吗?对于pg文档,由于性能下降,这种方法非常不可取。如果执行2次INSERT而不是1次INSERT,将危及应用程序的性能,那么
节点postgres
,根本不适合你。但我相信你看得不对,试图优化你不应该优化的地方。该库可以在1秒内轻松插入10000条记录。您的回答令人满意吗?如果是这样的话,请接受它。这对于少量的插入很好,但是对于数百个插入,您需要循环中的某些内容。此外,您的第二个建议可能会受到SQL注入的影响。您可能会对类型使用
NULL::table
,尽管您需要
选择
插入中列出的相同的单独列。
。太棒了,非常有魅力!!!
await db.query(sql`
  INSERT INTO table_name (name, email)
  VALUES ${sql.join(users.map(u => sql`(${u.name}, ${u.email})`), ',')}
`)