Javascript 如何一次插入两个表?准备好的发言
如何一次插入两个表?Javascript 如何一次插入两个表?准备好的发言,javascript,sql,node.js,postgresql,Javascript,Sql,Node.js,Postgresql,如何一次插入两个表? 我需要插入第二个表user\u information字段user\u id,第一个表userinsert返回id,我找到了,但我找不到如何使用params准备好的语句 var dbQuery = 'WITH insertUser AS ( INSERT INTO "user" (status, create_date) VALUES ($1, $2) RETURNING id ) , insertUserInformation AS ( INSERT IN
我需要插入第二个表
user\u information
字段user\u id
,第一个表user
insert返回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]);
我认为这不能作为一个自然的sql语句来完成。您必须将其包装为一个过程或其他机制。这在postgresql中是不可能的。通过创建函数并简单地使用参数执行,我解决了完全相同的问题。正如我在表结构中看到的,您没有很多属性,因此这将相对容易 示例代码:
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');
请注意,第二条insert语句将知道最近用户的id,并将使用它。使用事务。这样,要么提交所有查询,要么不提交任何查询。执行所有查询之前的未完成状态对于其他进程不可见 有关如何在
节点postgres
中执行事务的更多信息,请访问
作为参考,最相关的部分是:
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准备的语句不允许您这样做。您必须使用事务处理 下面是使用ES7语法实现的示例:
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;
});
谢谢你的回复,你能给我举个例子吗?我编辑了答案。我不熟悉node postgres,所以您必须自己连接这两种技术。只需使用事务即可。如果第二次查询失败,您可以执行回滚,数据库仍将处于一致状态,几乎就像什么都没有发生一样。默认情况下,postgresql中的所有函数都在事务范围内运行,因此在客户端代码中是否有事务无关紧要。请使用类似@Fka PROFERE的事务或查询,有什么不同的表现或其他问题吗?比如:这些答案对你有帮助吗?如果是这样的话,请接受它。你完全可以在Postgres中的一条SQL语句中实现这一点,正如文章所示。也许你不能用绑定的参数来实现,但除此之外,这当然是可能的。对不起,但是帖子显示使用了两个不同的sql语句。我不是说你的方法不正确,而是说它不能在一个自然的SQL语句中完成。这是异步工作的吗?如果同时调用执行此代码的函数的10000个实例,是否保证postgres驱动程序不会收到无效语句?(例如,紧接着另一个“开始”的“开始”语句)