Bazı yanıtlar kalıbı kullanmayı önerdi: rolün var olup olmadığını kontrol edin ve yoksa CREATE ROLE
komut verin. Bunun bir dezavantajı var: yarış durumu. Başka biri kontrol etme ve verme CREATE ROLE
komutu arasında yeni bir rol yaratırsa, o zamanCREATE ROLE
açıkça ölümcül bir hatayla başarısız olur.
Soruna yukarıda çözmek için, daha başka cevaplar zaten kullanımını söz PL/pgSQL
veren, CREATE ROLE
koşulsuz ve daha sonra bu çağrısından durumları yakalamak. Bu çözümlerle ilgili yalnızca bir sorun var. Rolün zaten var olduğu gerçeğiyle oluşmayanlar da dahil olmak üzere tüm hataları sessizce atarlar. CREATE ROLE
başka hatalar da atabilir ve simülasyon IF NOT EXISTS
yalnızca rol zaten mevcut olduğunda hatayı susturmalıdır.
CREATE ROLE
atmak duplicate_object
rolü zaten var olduğunda hata. Ve istisna işleyicisi yalnızca bu tek hatayı yakalamalıdır. Diğer cevaplarda belirtildiği gibi, ölümcül hatayı basit bildirime dönüştürmek iyi bir fikirdir. Diğer PostgreSQL IF NOT EXISTS
komutları , skipping
mesajlarına ekler , bu nedenle tutarlılık için buraya da ekliyorum.
CREATE ROLE IF NOT EXISTS
Doğru istisna ve sqlstate yayılımı ile simülasyonu için tam SQL kodu :
DO $$
BEGIN
CREATE ROLE test;
EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
END
$$;
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=# DO $$
postgres$# BEGIN
postgres$# CREATE ROLE test;
postgres$# EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
DO
postgres=#
postgres=# DO $$
postgres$# BEGIN
postgres$# CREATE ROLE test;
postgres$# EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
postgres$# END
postgres$# $$;
NOTICE: 42710: role "test" already exists, skipping
LOCATION: exec_stmt_raise, pl_exec.c:3165
DO
postgres=#
postgres=# CREATE ROLE test;
ERROR: 42710: role "test" already exists
LOCATION: CreateRole, user.c:337