2009-04-07 6 views
10

की वजह से फेंक दिया गया था, जबकि डालने अगर एक SQLException एक नकली चाबी की वजह से फेंक दिया गया था।पता करें कि एक SQLException, मैं एक जावा प्रोग्राम है कि डेटाबेस से नास्तिक है और मुझे पता है की जरूरत है एक नकली

यदि मैं एक डेटाबेस ड्राइवर का उपयोग कर रहा था तो मैं केवल त्रुटि कोड का उपयोग करता हूं, लेकिन चूंकि मैं बहुत अलग इंजनों का उपयोग कर सकता हूं क्योंकि त्रुटि कोड समान नहीं है।

क्या किसी ने इससे पहले किया है? कोई विचार?

कई टीआईए!

संपादित करें: मैं एक विन्यास फाइल जहाँ मैं ड्राइवर वर्ग की दुकान है (यानी: org.apache.derby.jdbc.ClientDriver) और कुछ अन्य आवश्यक जानकारी (यानी: उपयोगकर्ता नाम, पासवर्ड, यूआरएल ...)। कनेक्शन हमेशा "java.SQL.Connection" के रूप में पारित किया जाता है, इसलिए मुझे वास्तव में परवाह नहीं है कि ड्राइवरों का क्या उपयोग किया जा रहा है।

+0

आप कोड में डेटा का उपयोग कैसे कर रहे हैं? क्या आप जेडीबीसी के माध्यम से जा रहे हैं या क्या आपके पास डेटाबेस विशिष्ट कक्षाएं हैं? –

+0

मेरे पास एक कॉन्फ़िगरेशन फ़ाइल है जहां ड्राइवर वर्ग और कनेक्शन पैरामीटर संग्रहीत हैं। – ferro

उत्तर

7

मूल जेडीबीसी के साथ, वास्तव में ऐसा करने का कोई तरीका नहीं है जो आप क्रॉस-डेटाबेस तरीके से कह रहे हैं। जैसा कि आपने बताया है getErrorCode का उपयोग किया जा सकता है, लेकिन आवश्यक विक्रेता-विशिष्ट त्रुटि कोड।

केवल तीन तरीके मैं इस के आसपास पाने के लिए देखें:

  1. ढांचे में किसी प्रकार का है कि सार्थक अपवादों को त्रुटि कोड से अनुवाद के सभी करता है (हाइबरनेट शायद इस करना होगा उपयोग, किसी और उल्लेख किया है कि वसंत करता है)
  2. अपनी डालने से पहले डुप्लिकेट मैन्युअल रूप से (एक चयन के साथ) की जांच करें। (यह 100% नहीं होगा, क्योंकि यह तकनीकी रूप से संभव है कि कोई आपकी क्वेरी के बाद एक सम्मिलित कर सकता था)।
  3. डालने पर कोई भी SQL अपवाद प्राप्त करने के बाद, उस आईडी के लिए क्वेरी करने का प्रयास करें। यदि आप वास्तव में मैच ढूंढ सकते हैं - आप पूरी तरह से सुनिश्चित हो सकते हैं कि आपको मिली त्रुटि डुप्लिकेट प्राथमिक कुंजी के कारण थी। (हालांकि यह संभव है कि कई समस्याएं थीं, और वास्तव में वह नहीं था जिसे फेंक दिया गया था)।

मेरी सिफारिश समस्या जितनी ज्यादा हो सके समस्या से बचने के लिए अपना कोड लिखना होगा, और फिर (यदि बिल्कुल जरूरी है), # 3 का उपयोग करें।

+0

# 3 विशेष रूप से अच्छी सलाह की तरह प्रतीत नहीं होता है क्योंकि यह समरूपता को अनदेखा करता है। यही है, क्या होगा यदि कुछ अन्य कनेक्शन प्रश्न में रिकॉर्ड हटा दिए गए या जोड़े गए, लेकिन इस कनेक्शन ने एक पूर्ण असंबंधित कारण के लिए अपवाद फेंक दिया? इस कनेक्शन के लिए एक पंक्ति को लॉक करने का कोई तरीका नहीं है, इसलिए यह साबित नहीं कर सकता कि यह एक है। (मुझे लगता है कि यह पूरी तालिका को लॉक कर सकता है, लेकिन तालिका में समवर्ती पहुंच को कम करता है।) वास्तव में, फिर, # 2 और # 3 में समान सहमति मुद्दे हैं; जो हमें # 1 के साथ एकमात्र व्यावहारिक विकल्प के रूप में छोड़ देता है। – MikeB

0

मेरा मानना ​​है कि एक सरल और विश्वसनीय तरीके से कुंजी डालने कर से पहले से मौजूद है, तो जाँच करने के लिए है। जैसा कि आपने सही तरीके से बताया है, प्रत्येक डेटाबेस में त्रुटि की रिपोर्ट करने का अपना तरीका है।

+0

यह इस बात पर निर्भर करता है कि कोड में डेटा का उपयोग कैसे किया जा रहा है। यह सवाल से स्पष्ट नहीं है, इसलिए मैं निश्चित रूप से यह नहीं कहूंगा कि यह "केवल" तरीका है। –

+0

मैं नहीं देख सकता कि कोड में डेटा कैसे पहुंचा जा रहा है, डालने पर डुप्लिकेट कुंजी को प्रभावित करेगा। हालांकि मैं यह नहीं कह सकता कि यह एकमात्र समाधान है। मेरा जवाब संशोधित किया गया है। – wentbackward

1

ठीक है, अगर आप यह बताने के लिए अपवाद पर भरोसा नहीं कर सकते कि इसे क्यों फेंक दिया गया है, तो आप तालिका से "चयन गिनती (*) के साथ अपवाद का पालन करके परीक्षण कर सकते हैं जहां key = @keyfailedtoinsert;"

दुर्भाग्य से, अपवाद आप तालिका नाम और प्रमुख नाम देने के लिए गारंटी नहीं है। कुछ मामलों में, जावा कोड जिसे जेडीबीसी चालक कहा जाता है, उसे कभी नहीं मिला हो सकता है, उदाहरण के लिए, यदि सम्मिलित एक संग्रहीत प्रक्रिया के साथ, या ट्रिगर में होता है।

तो आप प्रत्येक JDBC ड्राइवर का विक्रेता पर विश्वास करने के लिए वापस आ गए हैं।

2

आप ज्ञात डुप्लिकेट कुंजी डालने और फेंकने वाले त्रुटि कोड को रिकॉर्ड करके स्टार्टअप (या कॉन्फ़िगरेशन) पर प्रोग्राम को "ट्रेन" कर सकते हैं।

+0

यह धारणा बनाता है कि लौटाई गई त्रुटि वास्तव में डालने पर डुप्लिकेट कुंजी है। आपके पास वास्तव में त्रुटि की पुष्टि करने का कोई तरीका नहीं है। – wentbackward

+0

@ वेंटबैकवर्ड - आप या तो 90% केस ले सकते हैं, और मान लें कि कनेक्ट करने, चयन करने, परीक्षण करने, चयन करने के बाद यह सही है और/या केवल उपयोगकर्ता को त्रुटि संदेश पढ़ने और पुष्टि करने के लिए कहें। यह एक सटीक विज्ञान नहीं है - लेकिन यह काफी करीब है। –

0

क्या मुझे कुछ याद आ रही है? यदि आप जेडीबीसी का उपयोग कर रहे हैं तो आपको डीबी का उपयोग किए जाने पर ध्यान दिए बिना डुप्लिकेट कुंजी अपवाद वापस लेना चाहिए।

या आप पूछा कि कैसे आप एक dupkey निर्धारित करेंगे इससे पहले कि आप तेह डालने की कोशिश की?

-1

मुझे लगता है कि आप जेडीबीसी का उपयोग नहीं कर रहे हैं या यह एक बहुत ही सरल त्रुटि लुकअप होगा।

क्या आपके पास अलग-अलग डेटाबेस तक पहुंचने के लिए कक्षाओं का एक अलग सेट है? यदि ऐसा है, तो आप डेटाबेस विशिष्ट कक्षाओं में अपवाद पकड़ सकते हैं और अपने स्वयं के अपवाद प्रकार को फेंक सकते हैं जो सभी डेटाबेस प्रकारों के बीच साझा किया जाता है।

2

मुझे लगता है कि आदर्श समाधान डेटा लेयर को इस मामले में एक विशिष्ट अपवाद फेंकना होगा, शायद DuplicateKeyException या कुछ समान के लिए SQLException का उप-वर्ग।

आप विभिन्न अपवादों को अलग ढंग से इलाज करने के लिए सक्षम होने के लिए चाहते हैं, तो आप अलग अलग प्रकार के अपवाद (या उप-प्रकार) के साथ शुरू करने के लिए फेंक करने के लिए है।

मुझे लगता है कि यह एक ऐसा क्षेत्र है जहां स्प्रिंग फ्रेमवर्क बातें वास्तव में सही हो जाता है: वे a very rich hierarchy of "database exceptions" जो सभी के DataAccessException का विस्तार, "वसूली योग्य अपवाद के लिए" प्रकार के उप पेड़ के साथ प्रदान करते हैं, "क्षणिक अपवाद", "डेटा अखंडता अपवाद" इत्यादि इत्यादि। यह आपके क्लाइंट कोड को अपवाद प्रकारों के किसी भी (या कोई भी) को पकड़ने के लिए मुक्त नहीं करता है, जो इसे संभाल सकता है या इसकी परवाह कर सकता है: अपवाद जो एक त्रुटि को इंगित करते हैं जो दोहराया जा सकता है यदि आप लेनदेन को फिर से चलाते हैं, एक घातक गैर- पुनर्प्राप्ति योग्य त्रुटि, या आप बस रूट प्रकार पकड़ सकते हैं।

8

यह वही है जो SQLException.getSQLState() के लिए है। Google के अनुसार, "23000" कम से कम MySQL, PostgreSQL, और Oracle में एक अद्वितीय बाधा उल्लंघन का संकेत देता है।

+1

उदाहरण के लिए डीबी 2 पर यह – ferro

+0

एचआरएम नहीं है, तो आप सही हैं। आपको समर्थन करने के लिए कितने डेटाबेस की आवश्यकता है? क्या यह वास्तव में एक अनंत संख्या है? एसक्यूएलस्टेट/एररकोड जोड़ी प्रत्येक डीबी के लिए क्या है, और उन सभी को संभालने के बारे में पता लगाने से बेहतर हो सकता है। यह अभी भी समय से पहले पंक्ति की जांच करने के लिए चयन करने से कहीं ज्यादा बेहतर प्रदर्शन करेगा। –

+0

मैं एक विधि बनाने जा रहा हूं जो डीबी कनेक्शन प्राप्त करेगा, यह जांचने के लिए कि कौन सा ड्राइवर उपयोग किया जा रहा है, और अपवाद, तो मैं getSQLState() की तुलना करूंगा और जांच सकता हूं कि यह डुप्लिकेट कुंजी है या नहीं। – ferro

संबंधित मुद्दे