কিছু উত্তর প্যাটার্ন ব্যবহার করার পরামর্শ দিয়েছে: ভূমিকাটির অস্তিত্ব নেই কিনা তা পরীক্ষা করুন এবং তা না হলে CREATE ROLEকমান্ড জারি করুন । এটির একটি অসুবিধা রয়েছে: জাতির শর্ত। যদি অন্য কেউ চেক এবং CREATE ROLEকমান্ড জারি করার মধ্যে একটি নতুন ভূমিকা তৈরি করে তবে CREATE ROLEঅবশ্যই মারাত্মক ত্রুটিতে ব্যর্থ হয়।
উপরের সমস্যা সমাধানের জন্য, আরও অন্যান্য উত্তর ইতিমধ্যে ব্যবহারের কথা উল্লেখ করেছে PL/pgSQL, CREATE ROLEনিঃশর্ত জারি করে এবং তারপরে সেই কল থেকে ব্যতিক্রম ধরা। এই সমাধানগুলির সাথে একটি মাত্র সমস্যা আছে। তারা নিঃশব্দে যে কোনও ত্রুটি বাদ দেয়, সেগুলি সহ যেগুলি ইতিমধ্যে ভূমিকাটি বিদ্যমান রয়েছে তা দ্বারা উত্পন্ন হয় না। CREATE ROLEঅন্যান্য ত্রুটিগুলিও ফেলে দিতে পারে এবং IF NOT EXISTSভূমিকা ইতিমধ্যে উপস্থিত থাকলে সিমুলেশনটি কেবল ত্রুটিটি নিঃশব্দ করা উচিত।
CREATE ROLEduplicate_objectভূমিকা ইতিমধ্যে উপস্থিত থাকলে ত্রুটি নিক্ষেপ করুন । এবং ব্যতিক্রম হ্যান্ডলার কেবল এই একটি ত্রুটি ধরা উচিত। অন্যান্য উত্তরের হিসাবে উল্লেখ করা হয়েছে যে মারাত্মক ত্রুটিটিকে সাধারণ নোটিশে রূপান্তর করা ভাল ধারণা। অন্যান্য PostgreSQL IF NOT EXISTSকমান্ডগুলি , skippingতাদের বার্তায় যুক্ত করে, তাই ধারাবাহিকতার জন্য আমি এটি এখানেও যুক্ত করছি।
CREATE ROLE IF NOT EXISTSসঠিক ব্যতিক্রম এবং স্ক্যালস্টেট প্রচারের সিমুলেশন করার জন্য এখানে সম্পূর্ণ এসকিউএল কোড রয়েছে :
DO $$
BEGIN
CREATE ROLE test;
EXCEPTION WHEN duplicate_object THEN RAISE NOTICE '%, skipping', SQLERRM USING ERRCODE = SQLSTATE;
END
$$;
পরীক্ষার আউটপুট (ডিও এর মাধ্যমে দু'বার বলা হয় এবং তারপরে সরাসরি):
$ 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