如何在 node-postgres 中构建 IF 语句?

How do I structure an IF statement in node-postgres?

我正在尝试在我的 node-postgres 事务中编写以下 IF 语句。这是为了通过检查字段的布尔值以获得唯一 ID before 在单独的 Table.

中插入和更新来使查询更健壮
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 语句替换底部的两个查询(saveQueryupdateQuery)。

我对 IF 语句的 BEGIN/END 语法和我通常在 node-postgres 中使用的事务的 BEGIN/COMMIT/ROLLBACK 语法感到困惑。我只是将前者放入后一个块吗?

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 语句是否被认为是一个事务,即如果查询的一部分失败,那么整个事情都会失败?谢谢。

经过反复试验,我得到了以下解决方案,并得到了澄清 post 的大量帮助。

is this IF statement above considered a transaction, i.e. if one part of the query fails, the whole thing fails? Thanks.

答案是否定的 - IF 语句的 BEGIN 与事务的 BEGIN 不同。有了这些知识,我认为可以在 BEGIN/COMMIT/ROLLBACK 块中插入 "IF" BEGIN/END 语句,现在可以回答以下问题:

How do I structure this in my node.js code?

        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,则执行 insertupdate 语句。如果 insert/update 语句失败,则整个事务失败。