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 DATABASE
tidak 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:
\gexec
Mengirim 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:
command
harus 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-c
pilihan.
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.