ORA-00907:दायां कोष्ठक गुम है
यह कई सामान्य त्रुटि संदेशों में से एक है जो दर्शाता है कि हमारे कोड में एक या अधिक सिंटैक्स त्रुटियां हैं। कभी-कभी इसका मतलब यह हो सकता है कि हमने सचमुच सही कोष्ठक छोड़ दिया है; यह सत्यापित करना काफी आसान है कि क्या हम एक ऐसे संपादक का उपयोग कर रहे हैं जिसमें मिलान ब्रैकेट . है क्षमता (कोडर्स के उद्देश्य से अधिकांश टेक्स्ट एडिटर करते हैं)। लेकिन अक्सर इसका मतलब है कि संकलक संदर्भ से बाहर एक खोजशब्द में आ गया है। या शायद यह एक गलत वर्तनी वाला शब्द है, अंडरस्कोर या लापता अल्पविराम के बजाय एक स्थान।
दुर्भाग्य से हमारे कोड के संकलित नहीं होने के संभावित कारण वस्तुतः अनंत हैं और संकलक उन्हें भेद करने के लिए पर्याप्त चतुर नहीं है। तो यह एक सामान्य, थोड़ा गुप्त, संदेश देता है जैसे ORA-00907: missing right parenthesis
और वास्तविक ब्लूमर को देखने के लिए इसे हम पर छोड़ देता है।
पोस्ट की गई स्क्रिप्ट में कई सिंटैक्स त्रुटियां हैं। सबसे पहले मैं उस त्रुटि के बारे में चर्चा करूंगा जो उस ORA-0097 को ट्रिगर करती है लेकिन आपको उन सभी को ठीक करना होगा।
सभी कॉलम घोषित होने के बाद विदेशी कुंजी बाधाओं को संदर्भित कॉलम के अनुरूप या तालिका स्तर पर घोषित किया जा सकता है। इनके अलग-अलग वाक्य-विन्यास हैं; आपकी स्क्रिप्ट दोनों को मिलाती हैं और इसीलिए आपको ORA-00907 मिलता है।
इन-लाइन घोषणा में अल्पविराम नहीं होता है और इसमें संदर्भ स्तंभ का नाम शामिल नहीं होता है।
CREATE TABLE historys_T (
history_record VARCHAR2 (8),
customer_id VARCHAR2 (8)
CONSTRAINT historys_T_FK FOREIGN KEY REFERENCES T_customers ON DELETE CASCADE,
order_id VARCHAR2 (10) NOT NULL,
CONSTRAINT fk_order_id_orders REFERENCES orders ON DELETE CASCADE)
तालिका स्तर की बाधाएं एक अलग घटक हैं, और इसलिए एक अल्पविराम है और संदर्भ स्तंभ का उल्लेख करें।
CREATE TABLE historys_T (
history_record VARCHAR2 (8),
customer_id VARCHAR2 (8),
order_id VARCHAR2 (10) NOT NULL,
CONSTRAINT historys_T_FK FOREIGN KEY (customer_id) REFERENCES T_customers ON DELETE CASCADE,
CONSTRAINT fk_order_id_orders FOREIGN KEY (order_id) REFERENCES orders ON DELETE CASCADE)
यहां अन्य सिंटैक्स त्रुटियों की सूची दी गई है:
- संदर्भित तालिका (और संदर्भित प्राथमिक कुंजी या अद्वितीय बाधा) पहले से मौजूद होनी चाहिए इससे पहले कि हम उनके खिलाफ एक विदेशी कुंजी बना सकें। इसलिए आप
HISTORYS_T
. के लिए एक विदेशी कुंजी नहीं बना सकते आपके द्वारा संदर्भितORDERS
. बनाने से पहले टेबल. - आपने कुछ विदेशी कुंजी खंडों (
LIBRARY_T
) में संदर्भित तालिकाओं के नामों की गलत वर्तनी की है औरFORMAT_T
) - आपको DEFAULT क्लॉज में एक एक्सप्रेशन देना होगा। DATE कॉलम के लिए जो आमतौर पर वर्तमान तिथि होती है,
DATE DEFAULT sysdate
।
अपने स्वयं के कोड को ठंडी नज़र से देखना एक ऐसा कौशल है जिसे हम सभी को डेवलपर्स के रूप में सफल होने के लिए हासिल करने की आवश्यकता है। यह वास्तव में Oracle के प्रलेखन से परिचित होने में मदद करता है। आपके कोड और SQL संदर्भ में उदाहरणों की साथ-साथ तुलना करने से आपको इन सिंटैक्स त्रुटियों को दो दिनों से भी कम समय में हल करने में मदद मिलेगी। इसे यहां (11g) और यहां (12c) ढूंढें।
सिंटैक्स त्रुटियों के साथ-साथ, आपकी स्क्रिप्ट में डिज़ाइन की गलतियाँ होती हैं। ये विफलताएं नहीं हैं, बल्कि बुरी आदत हैं जो आदत नहीं बननी चाहिए।
- आपने अपनी अधिकांश बाधाओं का नाम नहीं दिया है। Oracle उन्हें एक डिफ़ॉल्ट नाम देगा लेकिन यह एक भयानक नाम होगा, और डेटा डिक्शनरी को समझने में कठिन बनाता है। स्पष्ट रूप से हर बाधा का नामकरण हमें भौतिक डेटाबेस को नेविगेट करने में मदद करता है। जब हमारा SQL एक बाधा उल्लंघन का दौरा करता है तो यह अधिक समझने योग्य त्रुटि संदेशों की ओर जाता है।
- अपनी बाधाओं को लगातार नाम दें।
HISTORY_T
इसमेंhistorys_T_FK
नामक बाधाएं हैं औरfk_order_id_orders
, जिनमें से कोई भी सहायक नहीं है। एक उपयोगी परंपरा है<child_table>_<parent_table>_fk
. तोhistory_customer_fk
औरhistory_order_fk
क्रमशः। - अलग-अलग बयानों के साथ बाधाओं को बनाना उपयोगी हो सकता है। टेबल बनाने के बाद प्राथमिक कुंजी और फिर विदेशी कुंजी ऊपर बताए गए निर्भरता क्रम के साथ समस्याओं से बचेंगी।
- आप चक्रीय विदेशी कुंजी बनाने का प्रयास कर रहे हैं
LIBRARY_T
. के बीच औरFORMATS
. आप अलग-अलग स्टेटमेंट में बाधाएं बनाकर ऐसा कर सकते हैं, लेकिन ऐसा न करें:पंक्तियों को सम्मिलित करते समय आपको समस्याएँ होंगी और विलोपन के साथ भी बदतर समस्याएँ होंगी। आपको अपने डेटा मॉडल पर पुनर्विचार करना चाहिए और दो तालिकाओं के बीच संबंध को मॉडल करने का एक तरीका खोजना चाहिए ताकि एक माता-पिता और दूसरा बच्चा हो। या शायद आपको एक अलग तरह के रिश्ते की जरूरत है, जैसे कि चौराहे की मेज। - अपनी स्क्रिप्ट में रिक्त पंक्तियों से बचें। कुछ उपकरण उन्हें संभाल लेंगे लेकिन कुछ नहीं करेंगे। हम उन्हें संभालने के लिए SQL*Plus को कॉन्फ़िगर कर सकते हैं लेकिन आवश्यकता से बचना बेहतर है।
LIBRARY_T
का नामकरण परंपरा बदसूरत है। एक अधिक अभिव्यंजक नाम खोजने का प्रयास करें जिसमें कीवर्ड क्लैश से बचने के लिए अनावश्यक प्रत्यय की आवश्यकता न हो।T_CUSTOMERS
customers
. के रूप में, आपकी अन्य तालिकाओं के साथ असंगत और पूरी तरह से अनावश्यक होने के कारण और भी बदसूरत है कीवर्ड नहीं है।
चीजों का नामकरण कठिन है। आपको विश्वास नहीं होगा कि मेरे पास वर्षों से टेबल नामों के बारे में है। सबसे महत्वपूर्ण बात निरंतरता है। अगर मैं डेटा डिक्शनरी को देखता हूं और T_CUSTOMERS
called नामक टेबल देखता हूं और LIBRARY_T
मेरी पहली प्रतिक्रिया भ्रम की स्थिति होगी। इन तालिकाओं को विभिन्न सम्मेलनों के साथ क्यों नामित किया गया है? क्या वैचारिक अंतर क्या यह व्यक्त करता है? तो, कृपया, एक नामकरण परंपरा पर निर्णय लें और उस पर टिके रहें। अपनी तालिका के नाम या तो सभी एकवचन या सभी बहुवचन बनाएं। जितना हो सके उपसर्ग और प्रत्यय से बचें; हम पहले से ही जानते हैं कि यह एक टेबल है, हमें T_
की आवश्यकता नहीं है या एक _TAB
.