PostgreSQL desteklemediği IF NOT EXISTSiçin CREATE DATABASEdeyimi. Yalnızca içinde desteklenir CREATE SCHEMA. Üstelik CREATE DATABASEişlemde ihraç edilemez, dolayısıyla DOistisnai 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 dblinkiç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/pgSQLtamamen 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 EXISTSCREATE SCHEMA IF NOT EXISTSCREATE DATABASEdblinkduplicate_databaseerrcode, skippingCREATE 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 DATABASEveri 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_databasehata için yakalama var . Yani gerçekten IF NOT EXISTSolması 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.