PostgreSQL का समर्थन नहीं करता IF NOT EXISTS
के लिए CREATE DATABASE
बयान। यह केवल में समर्थित है CREATE SCHEMA
। इसके अलावा CREATE DATABASE
लेनदेन में जारी नहीं किया जा सकता है इसलिए यह DO
अपवाद पकड़ने के साथ ब्लॉक में नहीं हो सकता है ।
जब CREATE SCHEMA IF NOT EXISTS
जारी किया जाता है और स्कीमा पहले से मौजूद होता है तो डुप्लिकेट ऑब्जेक्ट जानकारी के साथ नोटिस (त्रुटि नहीं) उठाया जाता है।
इन समस्याओं को हल करने के लिए आपको dblink
एक्सटेंशन का उपयोग करना होगा जो डेटाबेस सर्वर के लिए एक नया कनेक्शन खोलता है और लेनदेन में प्रवेश किए बिना क्वेरी निष्पादित करता है। आप खाली स्ट्रिंग की आपूर्ति के साथ कनेक्शन मापदंडों का पुन: उपयोग कर सकते हैं।
नीचे PL/pgSQL
कोड है जो पूरी तरह 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
$$;
यह समाधान अन्य उत्तरों की तरह किसी भी दौड़ की स्थिति के बिना है, जहां डेटाबेस मौजूद है और अगर इसकी रचना है, तो जाँच के बीच बाहरी प्रक्रिया (या उसी स्क्रिप्ट के अन्य उदाहरण) द्वारा डेटाबेस बनाया जा सकता है।
इसके अलावा जब CREATE DATABASE
डेटाबेस से पहले अन्य त्रुटि के साथ विफल रहता है तो यह त्रुटि त्रुटि के रूप में प्रचारित की जाती है और चुपचाप त्याग नहीं की जाती है। केवल duplicate_database
त्रुटि के लिए पकड़ है । तो यह वास्तव में व्यवहार IF NOT EXISTS
करना चाहिए।
आप इस कोड को अपने कार्य में लगा सकते हैं, इसे सीधे या लेनदेन से बुला सकते हैं। बस रोलबैक (गिरा हुआ डेटाबेस पुनर्स्थापित करें) काम नहीं करेगा।
परीक्षण उत्पादन (दो बार के माध्यम से और फिर सीधे कहा जाता है):
$ 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
।