यह इस बात पर निर्भर करता है कि आप वास्तव में क्या परीक्षण करना चाहते हैं ।
सूचना स्कीमा?
यह पता लगाने के लिए कि "तालिका मौजूद है" ( कोई फर्क नहीं पड़ता कि कौन पूछ रहा है ), सूचना स्कीमा ( information_schema.tables
) को गलत बताते हुए, सख्ती से बोल रहा है, क्योंकि ( प्रति प्रलेखन ):
केवल उन तालिकाओं और विचारों को दिखाया गया है कि वर्तमान उपयोगकर्ता की पहुंच है (स्वामी होने के नाते या कुछ विशेषाधिकार होने के कारण)।
@Kong द्वारा प्रदान की गई क्वेरी वापस आ सकती है FALSE
, लेकिन तालिका अभी भी मौजूद हो सकती है। यह सवाल का जवाब देता है:
यह कैसे जांचें कि क्या एक तालिका (या दृश्य) मौजूद है, और वर्तमान उपयोगकर्ता की पहुंच है?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
सूचना स्कीमा मुख्य रूप से प्रमुख संस्करणों में और विभिन्न आरडीबीएमएस के पार पोर्टेबल रहने के लिए उपयोगी है। लेकिन कार्यान्वयन धीमा है, क्योंकि पोस्टग्रेज को मानक का पालन करने के लिए परिष्कृत विचारों का उपयोग करना पड़ता है ( information_schema.tables
यह एक सरल उदाहरण है)। और कुछ जानकारी (जैसे ओआईडी) सिस्टम कैटलॉग से अनुवाद में खो जाती है - जो वास्तव में सभी जानकारी ले जाती है।
सिस्टम कैटलॉग
आपका प्रश्न था:
कैसे जांचें कि क्या कोई तालिका मौजूद है?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
AND c.relkind = 'r' -- only tables
);
सिस्टम कैटलॉग का उपयोग करें pg_class
और pg_namespace
सीधे, जो भी काफी तेज है। हालाँकि, प्रति प्रलेखनpg_class
:
सूची pg_class
कैटलॉग टेबल और बाकी सबसे सब कुछ है कि स्तंभ होते हैं या नहीं तो एक मेज के समान है। इसमें अनुक्रमित (लेकिन यह भी देखें pg_index
), अनुक्रम , विचार , भौतिक विचार , समग्र प्रकार और टोस्ट टेबल शामिल हैं ;
इस विशेष प्रश्न के लिए आप सिस्टम दृश्य काpg_tables
उपयोग कर सकते हैं । प्रमुख पोस्टग्रेज संस्करणों में थोड़ा सरल और अधिक पोर्टेबल (जो इस मूल प्रश्न के लिए चिंता का विषय नहीं है):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
ऊपर उल्लिखित सभी वस्तुओं के बीच पहचानकर्ता अद्वितीय होना चाहिए । यदि आप पूछना चाहते हैं:
यह कैसे जांचें कि किसी दिए गए स्कीमा में तालिका या इसी तरह की वस्तु का नाम लिया गया है?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
);
वैकल्पिक: कास्ट करने के लिए regclass
SELECT 'schema_name.table_name'::regclass
यह एक अपवाद उठाता है यदि वैकल्पिक रूप से स्कीमा-योग्य) तालिका (या उस नाम पर कब्जा करने वाली अन्य वस्तु) मौजूद नहीं है।
यदि आप तालिका के नाम को स्कीमा-अर्हता प्राप्त नहीं करते हैं, तो पहली तालिका के लिए OID को regclass
चूक करने search_path
और वापस करने के लिए एक कास्ट मिला है - या एक अपवाद यदि तालिका सूचीबद्ध स्कीमा में से कोई भी नहीं है। ध्यान दें कि सिस्टम स्कीमाpg_catalog
और pg_temp
(वर्तमान सत्र की अस्थायी वस्तुओं के लिए स्कीमा) स्वचालित रूप से इसका हिस्सा हैं search_path
।
आप इसका उपयोग कर सकते हैं और एक फ़ंक्शन में एक संभावित अपवाद को पकड़ सकते हैं। उदाहरण:
ऊपर की तरह एक क्वेरी संभव अपवाद से बचा जाता है और इसलिए थोड़ा तेज है।
बहुत सरल अब:
SELECT to_regclass('schema_name.table_name');
कलाकारों के रूप में भी, लेकिन यह रिटर्न ...
... यदि नाम नहीं मिला है, तो एक त्रुटि को फेंकने के बजाय अशक्त करें
[[ `psql dbname -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'ejabberd' AND table_name = 'users');"` = 't' ]]