如何一次插入两张表? 准备好陈述

如何一次插入两个表?
我需要插入第二个表user_information字段user_id与第一个表user插入返回id ,我发现这个答案,但我找不到如何与params准备语句

 var dbQuery = 'WITH insertUser AS ( INSERT INTO "user" (status, create_date) VALUES ($1, $2) RETURNING id ) , insertUserInformation AS ( INSERT INTO user_information (user_id, email) VALUES ($3, $4) ) '; yield queryPromise(dbClient, dbQuery, [status, timestamp, ??, email]); 

皮克

使用交易。 这样或者所有的查询都会被提交,或者没有提交。 执行所有查询之前的不完整状态对其他进程不可见。

有关如何在node-postgres执行事务的更多信息, 请访问https://github.com/brianc/node-postgres/wiki/Transactions

而作为参考,最相关的部分是:

 var Client = require('pg').Client; var client = new Client(/*your connection info goes here*/); client.connect(); var rollback = function(client) { //terminating a client connection will //automatically rollback any uncommitted transactions //so while it's not technically mandatory to call //ROLLBACK it is cleaner and more correct client.query('ROLLBACK', function() { client.end(); }); }; client.query('BEGIN', function(err, result) { if(err) return rollback(client); client.query('INSERT INTO account(money) VALUES(100) WHERE id = $1', [1], function(err, result) { if(err) return rollback(client); client.query('INSERT INTO account(money) VALUES(-100) WHERE id = $1', [2], function(err, result) { if(err) return rollback(client); //disconnect after successful commit client.query('COMMIT', client.end.bind(client)); }); }); }); 

在postgresql中是不可能的。 我通过创build函数并简单地使用参数执行来解决完全相同的问题。 正如我在你的表格结构中看到的那样,你没有很多属性,所以这会比较容易。

示例代码:

function.sql

 CREATE OR REPLACE FUNCTION createSomething ( IN attr1 VARCHAR(20), IN attr2 VARCHAR(200) ) RETURNS void AS $$ DECLARE userId INTEGER; BEGIN INSERT INTO table1 (col1, col2) VALUES ( attr1, attr2 ) RETURNING id INTO userId; INSERT INTO table2 (user_id, col11, col2) VALUES ( userId, col11, col12 ); END; $$ LANGUAGE plpgsql; 

用法:

 SELECT createSomething('value1', 'value2'); 

请注意,第二个插入语句将知道最近用户的ID是什么,并将使用它。

PostgreSQL准备好的语句不会让你这样做。 您将不得不使用交易。

下面是使用ES6生成器实现pg-promise的示例,因为这似乎是您的问题的偏好。

 var pgp = require('pg-promise')({ // initialization options; }); var db = pgp(/* your connection object or string */); db.tx(function*(t) { let user = yield t.one('INSERT INTO user(status, create_date) VALUES($1, $2) RETURNING id', [status, timestamp]); yield t.none('INSERT INTO user_information(user_id, email) VALUES($1, $2)', [user.id, email]); }) .then(()=> { // SUCCESS; }) .catch(error=> { // ERROR; }); 

或者你可以使用db.tx的结果进一步yield ,因为它返回一个承诺。

我不相信这可以作为一个自然的sql语句来完成。 你必须把它作为一个过程或其他机制来包装起来。