Reputation: 1088
How to insert two table in one time?
I need to insert second table user_information
the field user_id
with first table user
insert returning id
, I found this answer but I can't find how to be with params prepared statements
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]);
Upvotes: 1
Views: 4721
Reputation: 25940
PostgreSQL Prepared Statements will not let you do it. You will have to use a transaction.
Below is your example implemented with pg-promise, using ES7 syntax:
const pgp = require('pg-promise')({
// initialization options;
});
const db = pgp(/* your connection object or string */);
db.tx(async t => {
const user = await t.one('INSERT INTO user(status, create_date) VALUES($1, $2) RETURNING id', [status, timestamp]);
return t.none('INSERT INTO user_information(user_id, email) VALUES($1, $2)', [user.id, email]);
})
.then(() => {
// SUCCESS;
})
.catch(error => {
// ERROR;
});
Upvotes: 1
Reputation: 6234
It's impossible in postgresql. I solved exact the same problem by creating function and simply executing with parameters. As I see in your table structure, you don't have many attributes, so this will be relatively easy.
Example code:
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;
Usage:
SELECT createSomething('value1', 'value2');
Please notice, that second insert statement will know what was recently user's id and will use it.
Upvotes: 2
Reputation: 9884
Use transactions. That way either all queries will be committed, or none will be committed. And the incomplete state before you have executed all queries is not visible for other processes.
More on how to do transactions in node-postgres
is available at https://github.com/brianc/node-postgres/wiki/Transactions
And for reference the most relevant section is:
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));
});
});
});
Upvotes: 2
Reputation: 333
I do not believe this can be accomplished as a natural sql statement. You have to wrap it up as a procedure or some other mechanism.
Upvotes: -1