如何使用node-postgres将多行正确插入PG?

时间:2016-01-25 10:24:06

标签: 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.com')"

我可以使用js字符串运算符手动编译这些行,但是我需要以某种方式添加特殊字符转义。

5 个答案:

答案 0 :(得分:3)

关注本文:来自Performance Boost库的pg-promise及其建议的方法:

// 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
    });

<强>更新

要通过单个INSERT查询获得高性能方法,请参阅Multi-row insert with pg-promise

答案 1 :(得分:3)

使用如下所示的pg格式npm。

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);
});

答案 2 :(得分:2)

使用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);
      }
});

答案 3 :(得分:1)

insert into tableName (name, email) values (" +var1 + "," + var2 + "),(" +var3 + ", " +var4+ ") "

没有帮助? 此外,您可以手动生成查询字符串:

become

如果你在这里阅读https://github.com/brianc/node-postgres/issues/530,你可以看到相同的实现。

答案 4 :(得分:0)

您将不得不动态生成查询。虽然可能,但这是有风险的,如果操作不当,很容易导致 SQL 注入漏洞。也很容易以查询中参数的索引和传入的参数之间的一个错误结束。

话虽如此,下面是一个如何编写此代码的示例,假设您有一组看起来像 {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,
)

另一种方法是使用像 @databases/pg 这样的库(我写的):

await db.query(sql`
  INSERT INTO table_name (name, email)
  VALUES ${sql.join(users.map(u => sql`(${u.name}, ${u.email})`), ',')}
`)

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