PostgreSQL desteklemediği IF NOT EXISTS
için CREATE DATABASE
deyimi. Yalnızca içinde desteklenir CREATE SCHEMA
. Üstelik CREATE DATABASE
işlemde ihraç edilemez, dolayısıyla DO
istisnai yakalama dışında blok halinde olamaz .
Ne zaman CREATE SCHEMA IF NOT EXISTS
yayınlandı ve şema zaten mevcutsa, yinelenen nesne bilgileriyle ilgili bir uyarı (hata değil) ortaya çıkar.
Bu sorunları çözmek dblink
için, veritabanı sunucusuna yeni bir bağlantı açan ve işleme girmeden sorgu yürüten uzantıyı kullanmanız gerekir . Boş dizge sağlayarak bağlantı parametrelerini yeniden kullanabilirsiniz.
Aşağıda, içindeki gibi aynı davranışı PL/pgSQL
tamamen simüle eden kod bulunmaktadır . Aracılığıyla , catch istisnasını çağırır (veritabanı zaten mevcut olduğunda verilir) ve bunu yayarak bildirime dönüştürür . Dize mesajı eklenmiş olan öyle nasıl aynı şekilde .CREATE DATABASE IF NOT EXISTS
CREATE SCHEMA IF NOT EXISTS
CREATE DATABASE
dblink
duplicate_database
errcode
, skipping
CREATE SCHEMA IF NOT EXISTS
CREATE EXTENSION IF NOT EXISTS dblink;
DO $$
BEGIN
PERFORM dblink_exec('', 'CREATE DATABASE testdb');
EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
END
$$;
Bu çözüm, diğer yanıtlarda olduğu gibi herhangi bir yarış koşulu içermez; burada veritabanı, veritabanının var olup olmadığını kontrol etmekle kendi yaratımı arasında harici işlem (veya aynı komut dosyasının başka bir örneği) tarafından oluşturulabilir.
Ayrıca, CREATE DATABASE
veri tabanı dışındaki başka bir hatayla başarısız olduğunda, bu hata hata olarak yayılır ve sessizce atılmaz. Sadece duplicate_database
hata için yakalama var . Yani gerçekten IF NOT EXISTS
olması gerektiği gibi davranıyor .
Bu kodu kendi işlevine koyabilir, doğrudan veya işlemden çağırabilirsiniz. Sadece geri alma (bırakılan veritabanını geri yükleme) çalışmaz.
Test çıkışı (DO aracılığıyla iki kez ve ardından doğrudan çağrılır):
$ sudo -u postgres psql
psql (9.6.12)
Type "help" for help.
postgres=# \set ON_ERROR_STOP on
postgres=# \set VERBOSITY verbose
postgres=#
postgres=# CREATE EXTENSION IF NOT EXISTS dblink;
CREATE EXTENSION
postgres=# DO $$
postgres$# BEGIN
postgres$# PERFORM dblink_exec('', 'CREATE DATABASE testdb');
postgres$# EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
DO
postgres=#
postgres=# CREATE EXTENSION IF NOT EXISTS dblink;
NOTICE: 42710: extension "dblink" already exists, skipping
LOCATION: CreateExtension, extension.c:1539
CREATE EXTENSION
postgres=# DO $$
postgres$# BEGIN
postgres$# PERFORM dblink_exec('', 'CREATE DATABASE testdb');
postgres$# EXCEPTION WHEN duplicate_database THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
NOTICE: 42P04: database "testdb" already exists, skipping
LOCATION: exec_stmt_raise, pl_exec.c:3165
DO
postgres=#
postgres=# CREATE DATABASE testdb;
ERROR: 42P04: database "testdb" already exists
LOCATION: createdb, dbcommands.c:467
dblink_connect
.