sql >> Databáze >  >> RDS >> PostgreSQL

Simulovat VYTVOŘIT DATABÁZI, POKUD NEEXISTUJE pro PostgreSQL?

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í.



  1. Rozdíl mezi uživatelem a schématem v Oracle?

  2. Najděte porušení cizího klíče v SQLite

  3. Jak získat záznamy za posledních 7 dní v MySQL

  4. špatný výběr výkonu Hibernate ve srovnání s přímým spuštěním - jak ladit?