Postgresql – Drop multiple databases in one script

pgadminpostgresqlpsqlscripting

I am trying to figure out how to drop multiple databases on PostgreSQL in one sql script. I preferably need it to work both when executed in pgAdmin console, and when used in psql command line tool. When I do:

DROP DATABASE db1;
DROP DATABASE db2;

I get following error:

DROP DATABASE cannot be executed from a function or multi-command string

Is there any way around this problem? I.e., is there any way to run each command separately (like when using "GO" statement on MSSQL), or some other sensible way to easily drop multiple databases? I need this functionality for maintenance scripts during development.

Best Answer

When executing multiple commands in a script in pgAdmin they are automatically wrapped into a transaction. You can explicitly begin and commit transactions, but not with commands that won't run in a transaction context. The manual:

DROP DATABASE cannot be executed inside a transaction block.

Similar in psql when called with -c command. The manual:

If the command string contains multiple SQL commands, they are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands included in the string to divide it into multiple transactions.

However, when fed to psql via standard input:

This is different from the behavior when the same string is read from a file or fed to psql's standard input, because then psql sends each SQL command separately.

Because of this behavior, putting more than one SQL command in a single -c string often has unexpected results. It's better to use repeated -c commands or feed multiple commands to psql's standard input, either using echo as illustrated above, or via a shell here-document, for example:

psql <<EOF
\x
SELECT * FROM foo;
EOF

So you can use psql with standard input in default autocommit-on mode.
Else, you can only run separate commands.

You could use the shell-command dropdb - or write a shell-script with it that drops multiple databases.

BTW, the only difference between what you can run from pgAdmin and psql are the meta-commands of psql - which are not SQL. Those are interpreted by psql and not the database engine. To switch between meta-commands and SQL, use the separator meta-command \\. There is an example in the manual.