0

I have a .sql script like this:

DO $$
    DECLARE     
    prev_count := (SELECT count(*) FROM ...);
END$$;

UPDATE [...]

DO $$
    DECLARE     
    cur_count := (SELECT count(*) FROM ...);
    BEGIN
    ASSERT cur_count = prev_count, 'Mismatch';
END$$;

In which I get some value, modify the database, and expect a new value to match an old value. However, I get errors like this:

psql:migration.sql:163: ERROR:  column "prev_count" does not exist
LINE 1: SELECT cur_count = prev_count
                              ^
QUERY:  SELECT cur_count = prev_count
CONTEXT:  PL/pgSQL function inline_code_block line 4 at ASSERT

I can't tell if this is a scoping issue because of the anonymous block, and why it's attempting to treat my variables like columns. Any ideas?

3
  • 4
    Have you tried single anonymous block? Demo Commented May 16, 2018 at 17:43
  • Looks like a scope issue and it is assuming prev_count is a column because the variable name prev_count no longer exists in the current scope. If this is a repeated task with a static update function I would probably just create a stored proc Commented May 16, 2018 at 18:14
  • @lad2025 I hadn't, thanks for the idea + code! Commented May 16, 2018 at 18:53

1 Answer 1

2

According to the manual DO executes an anonymous code block that:

... is treated as though it were the body of a function with no parameters, returning void. It is parsed and executed a single time...

So it is a function that returns VOID. In that sense prev_count only exists in the first DO.

To avoid this, you could create a TEMP table and insert the prev_count in the first DO so you can use it anywhere in the transaction.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.