Omezení
Můžete se zeptat na systémový katalog pg_database
- přístupné z libovolné databáze ve stejném databázovém clusteru. Záludná část je v tom, že CREATE DATABASE
lze provést pouze jako jeden příkaz. Manuál:
CREATE DATABASE
nelze provést uvnitř transakčního bloku.
Nelze jej tedy spustit přímo uvnitř funkce nebo DO
příkaz, kde by byl implicitně uvnitř transakčního bloku. Ani s tím nepomohou SQL procedury zavedené s Postgres 11.
Řešení z psql
Můžete to obejít z psql podmíněným provedením příkazu DDL:
SELECT 'CREATE DATABASE mydb'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec
Manuál:
\gexec
Odešle aktuální vyrovnávací paměť dotazu na server a poté zpracuje každý sloupec každého řádku výstupu dotazu (pokud existuje) jako příkaz SQL, který se má provést.
Řešení z prostředí shell
Pomocí \gexec
stačí zavolat psql jednou :
echo "SELECT 'CREATE DATABASE mydb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec" | psql
Možná budete potřebovat více možností psql pro vaše připojení; role, port, heslo, ... Viz:
- Spusťte dávkový soubor pomocí příkazu psql bez hesla
Totéž nelze volat pomocí psql -c "SELECT ...\gexec"
od \gexec
je meta-příkaz psql a -c
volba očekává jeden příkaz pro který manuál uvádí:
command
musí být buď příkazový řetězec, který je zcela analyzovatelný serverem (tj. neobsahuje žádné funkce specifické pro psql), nebo jeden příkaz zpětného lomítka. Nemůžete tedy kombinovat meta-příkazy SQL a psql v-c
možnost.
Řešení v rámci transakce Postgres
Můžete použít dblink
připojení zpět k aktuální databázi, která běží mimo transakční blok. Efekty proto také nelze vrátit zpět.
K tomu nainstalujte přídavný modul dblink (jednou na databázi):
- Jak používat (instalovat) dblink v PostgreSQL?
Potom:
DO
$do$
BEGIN
IF EXISTS (SELECT FROM pg_database WHERE datname = 'mydb') THEN
RAISE NOTICE 'Database already exists'; -- optional
ELSE
PERFORM dblink_exec('dbname=' || current_database() -- current db
, 'CREATE DATABASE mydb');
END IF;
END
$do$;
Opět možná budete potřebovat více možností psql pro připojení. Viz přidaná Ortwinova odpověď:
- Simulovat VYTVOŘIT DATABÁZI, POKUD NEEXISTUJE pro PostgreSQL?
Podrobné vysvětlení pro dblink:
- Jak provedu velké neblokující aktualizace v PostgreSQL?
Tuto funkci můžete použít pro opakované použití.