我正在尝试在node-postgres
事务中编写以下IF语句。这是为了通过在在插入和更新到单独的表中之前检查字段的布尔值以获得唯一ID来使查询更加健壮。
DO $$
BEGIN
IF (SELECT has_submitted FROM schema1.analysis_sent WHERE unique_link = 'aaa') THEN
RAISE EXCEPTION 'Already submitted questions.';
ELSE
INSERT INTO schema1.question_breakdown (question_id) VALUES (1);
UPDATE schema1.analysis_sent SET has_submitted = TRUE WHERE unique_link = 'aaa';
RAISE NOTICE 'Added to question_breakdown and updated has_submitted field.';
END IF;
END $$;
如何在node.js中构造此结构,特别是使用node-postgres包?当前,它看起来像以下内容,我想用上面的IF语句替换底部的两个查询(saveQuery
和updateQuery
)。
我对IF语句的BEGIN/END
语法和通常在BEGIN/COMMIT/ROLLBACK
中使用的事务的node-postgres
语法感到困惑。我是否可以将前者放到后者中?
const saveQuery = format('INSERT INTO %I.question_breakdown_result(question_id, student_id, marks_scored) VALUES %L', org, questions);
const updateQuery = format('UPDATE %I.analysis_sent SET has_submitted = TRUE WHERE unique_link = %L', org, link.uniqueLink);
(async() => {
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query(saveQuery);
await client.query(updateQuery);
await client.query('COMMIT');
return res.status(201).json(helper.setResponsePayload(true, 'Your results have been saved and submitted.', null));
} catch (err) {
await client.query('ROLLBACK');
res.status(200).json(helper.setResponsePayload(false, 'Failed Database Query: Save Question Result.', null));
throw err;
} finally {
client.release();
}
})().catch(err => console.log(err.stack))
第二个问题-上面的IF语句是否被视为事务,即,如果查询的一部分失败,那么整个事情都会失败?谢谢。
答案 0 :(得分:0)
经过反复试验,在弄清楚post的帮助下,我提出了以下解决方案。
上面的IF语句是否被视为交易,即是否一部分 查询失败,整个事情失败了吗?谢谢。
答案是否定的-IF语句的BEGIN
与事务的BEGIN
不同。有了这些知识,我认为可以在BEGIN/END
块中插入“ IF” BEGIN/COMMIT/ROLLBACK
语句,现在可以回答以下问题:
如何在我的node.js代码中构造它?
const checkQuery = format('SELECT has_submitted FROM %I.analysis_sent WHERE unique_link = %L', org, link.uniqueLink);
const saveQuery = format('INSERT INTO %I.question_breakdown_result(question_id, student_id, marks_scored) VALUES %L', org, questions);
const updateQuery = format('UPDATE %I.analysis_sent SET has_submitted = TRUE WHERE unique_link = %L', org, link.uniqueLink);
const ifQuery = `
DO $$
BEGIN
IF (${checkQuery}) THEN
RAISE EXCEPTION 'User has already submitted paper questions.';
ELSE
${saveQuery};
${updateQuery};
RAISE NOTICE 'Added to question_breakdown and updated has_submitted field.';
END IF;
END $$;
`;
(async() => {
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query(ifQuery);
await client.query('COMMIT');
} catch (err) {
await client.query('ROLLBACK');
throw err;
} finally {
client.release();
}
})().catch(err => console.log(err.stack));
现在它按计划工作:检查唯一ID的字段是否为TRUE
;如果FALSE
,则执行insert
和update
语句。如果insert
/ update
语句失败,则整个事务都会失败。