Pembatasan
Anda dapat menanyakan katalog sistem pg_database - dapat diakses dari database mana pun dalam cluster database yang sama. Bagian yang sulit adalah CREATE DATABASE hanya dapat dieksekusi sebagai satu pernyataan. Panduan:
CREATE DATABASEtidak dapat dieksekusi di dalam blok transaksi.
Jadi tidak dapat dijalankan langsung di dalam suatu fungsi atau DO pernyataan, di mana itu akan berada di dalam blok transaksi secara implisit. Prosedur SQL, yang diperkenalkan dengan Postgres 11, juga tidak dapat membantu.
Solusi dari dalam psql
Anda dapat mengatasinya dari dalam psql dengan mengeksekusi pernyataan DDL secara kondisional:
SELECT 'CREATE DATABASE mydb'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec
Panduan:
\gexecMengirim buffer kueri saat ini ke server, lalu memperlakukan setiap kolom dari setiap baris output kueri (jika ada) sebagai pernyataan SQL yang akan dieksekusi.
Solusi dari shell
Dengan \gexec Anda hanya perlu memanggil psql sekali :
echo "SELECT 'CREATE DATABASE mydb' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'mydb')\gexec" | psql
Anda mungkin memerlukan lebih banyak opsi psql untuk koneksi Anda; peran, port, kata sandi, ... Lihat:
- Jalankan file batch dengan perintah psql tanpa kata sandi
Hal yang sama tidak dapat dipanggil dengan psql -c "SELECT ...\gexec" sejak \gexec adalah perintah meta psql dan -c opsi mengharapkan satu perintah yang dinyatakan dalam manual:
commandharus berupa string perintah yang sepenuhnya dapat diuraikan oleh server (yaitu, tidak berisi fitur khusus psql), atau satu perintah garis miring terbalik. Jadi Anda tidak dapat mencampur perintah meta SQL dan psql dalam-cpilihan.
Solusi dari dalam transaksi Postgres
Anda dapat menggunakan dblink koneksi kembali ke database saat ini, yang berjalan di luar blok transaksi. Oleh karena itu, efek juga tidak dapat dibatalkan.
Instal modul tambahan dblink untuk ini (sekali per database):
- Bagaimana cara menggunakan (menginstal) dblink di PostgreSQL?
Kemudian:
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$;
Sekali lagi, Anda mungkin memerlukan lebih banyak opsi psql untuk koneksi. Lihat jawaban tambahan Ortwin:
- Simulasikan CREATE DATABASE JIKA TIDAK ADA untuk PostgreSQL?
Penjelasan detail untuk dblink:
- Bagaimana cara melakukan pembaruan besar tanpa pemblokiran di PostgreSQL?
Anda dapat menjadikan ini fungsi untuk penggunaan berulang.