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

时间:2019-11-28 05:53:22

标签: node.js postgresql node-postgres

我正在尝试在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语句替换底部的两个查询(saveQueryupdateQuery)。

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

1 个答案:

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