Node.js 如何在事务中插入多行(来自请求主体)

Node.js 如何在事务中插入多行(来自请求主体),node.js,postgresql,node-postgres,Node.js,Postgresql,Node Postgres,我想问一下是否有办法通过req插入多行。身体(来自前端)。我已经设法创建了一种插入一行的方法,但是如果可能的话,我想插入多行task,而只插入job一次 我读到一种方法是使用json数组并循环它,但不知道如何做。如果你有其他的方法,那也将是一个很大的帮助 我目前使用node.js/express.js作为后端,node postgres作为到db的连接 //2. Declare an asynchronous function for the PG transaction asy

我想问一下是否有办法通过req插入多行。身体(来自前端)。我已经设法创建了一种插入一行的方法,但是如果可能的话,我想插入多行
task
,而只插入
job
一次

我读到一种方法是使用json数组并循环它,但不知道如何做。如果你有其他的方法,那也将是一个很大的帮助

我目前使用node.js/express.js作为后端,node postgres作为到db的连接

//2. Declare an asynchronous function for the PG transaction
        async function execute() {
            // Promise chain for pg Pool client
            const client = await pool
                .connect()

                .catch(err => {
                    console.log("\nclient.connect():", err.name);

                    // iterate over the error object attributes
                    for (item in err) {
                        if (err[item] = undefined) {
                            process.stdout.write(item + " - " + err[item] + " ");
                        }
                    }

                    //end the Pool instance
                    console.log("\n");
                    process.exit();
                });

                try {
                    //Initiate the Postgres transaction
                    await client.query("BEGIN");

                    try {
                        const sqlString = `WITH INSERTED AS (
                            INSERT INTO jobs (job_name) VALUES
                                ($1) RETURNING id)
                            INSERT INTO tasks(
                                employee_id, job_id) VALUES
                                ($2,(
                                    SELECT id FROM inserted
                                ))`;
                        
                        const sqlValues = [job_name, employee_id
                        ];

                        // Pass SQL string to the query() method
                        await client.query(sqlString, sqlValues, function(err, result) {
                            console.log("client.query() SQL result:", result);

                            if (err) {
                            console.log("\nclient.query():", err);

                            // Rollback before executing another transaction
                            client.query("ROLLBACK");
                            console.log("Transaction ROLLBACK called");
                            } else {
                            client.query("COMMIT");
                            console.log("client.query() COMMIT row count:", result.rowCount);
                            }
                        });

                    } catch (er) {
                        // Rollback before executing another transaction
                        client.query("ROLLBACK");
                        console.log("client.query():", er);
                        console.log("Transaction ROLLBACK called");
                    }
                } finally {
                    client.release();
                    console.log("Client is released");
                }
        }

        execute();

        } catch (err) {
            console.error(err.message);
            res.status(500).send("Server Error");
    }
});

谢谢大家!

在第二个INSERT和UNNEST()中使用SELECT从数组中获取所有项:

WITH INSERTED AS (  
    INSERT INTO jobs (job_name) 
    VALUES($1) 
    RETURNING id
)
INSERT INTO tasks(employee_id, job_id) 
SELECT  UNNEST($2) -- PostgreSQL array input, you might need another function for your type of input
    ,   id
FROM inserted;
编辑:使用一些json对象作为输入的示例:

WITH INSERTED AS (  
    INSERT INTO jobs (job_name) 
    VALUES($1::json #>> '{name}') -- selects the name from the json object as TEXT
    RETURNING id
)
INSERT INTO tasks(employee_id, job_id) 
SELECT  column1 
    ,   id
FROM inserted
    , json_to_recordset($1::json #> '{tasks}') AS t(column1 int, column2 text);

$1是一个使用两次的json对象。PostgreSQL将提取插入所需的元素。

当您有两个不同的项目要插入时,您确定要使用$1两次吗?@FrankHeikens Oops,我没有注意到输入错误。非常感谢。修正(第二个应该是2美元)嗨,抱歉,但是你能解释一下unnest的工作原理吗?我已经阅读了文档并查看了其他资源,但对我来说仍然有点模糊。如果我错了,请纠正我,但据我所知,我可以使用
unest
从req.body打开对象数组(json)。我应该如何格式化我的数组?我读到它应该是
“arrayName”:[{“Row1col1:“Row1value1”,“Row1col2:“Row1value2”}.{“Row2col1:“Row2value1”,“Row2col2:“row2value2”}]
如果这个问题可能是我在阅读文档时容易漏掉的,那么我向您表示感谢和歉意。@TechArtificer:您能给我们看一个有效的json对象吗?下面是我计划通过req.body发送到db的内容。json中的示例假设插入的数据将有多个列,而不是只有一列(与我上面发布的代码相反)并使用不同的数据类型(int和string),以防万一我将来可能需要它作为附加参考。@TechArtificer:请参阅新示例,仅使用一个输入参数,即您向我们展示的完整json对象。您好,我“认为”“它的工作原理是我能够读取并接受json,但我有一个错误,上面写着
'Expected:”,但找到了“}”.
我检查了Google,这似乎是一个问题,我尝试在sqlValues
tasks
上使用JSON.stringify,但仍然返回错误。感谢您的帮助!呃,如果我可以问一下,是否可以在事务中设置条件?例如,您不能插入同一个员工id两次,或者检查员工id是否已读取表中是否存在y?