2010-10-08 15 views
11

नीचे दिए गए कोड में, pathToNonDatabase एक साधारण टेक्स्ट फ़ाइल का पथ है, वास्तविक SQL डेटाबेस नहीं। मैं इसका पता लगाने के लिए sqlite3_open की उम्मीद कर रहा था, लेकिन यह नहीं (dbNULL नहीं है, और resultSQLITE_OK है)। तो, यह पता लगाने के लिए कि एक फ़ाइल एक वैध sqlite डेटाबेस नहीं है?कैसे बताएं कि sqlite डेटाबेस फ़ाइल मान्य है या नहीं

sqlite3 *db = NULL; 
int result = sqlite3_open(pathToNonDatabase, &db); 

if((NULL==db) || (result!=SQLITE_OK)) { 
    // invalid database 
} 

उत्तर

12

वर्गमीटर डेटाबेस को आलसी खोलता है। खोलने के तुरंत बाद कुछ करें जो इसे डेटाबेस होने की आवश्यकता है।

सबसे अच्छा शायद pragma schema_version; है।

  • यदि डेटाबेस नहीं बनाया गया है (उदाहरण के लिए, एक खाली फ़ाइल) तो यह 0 की रिपोर्ट करेगा। इस मामले में, यह सुरक्षित काम है (और CREATE TABLE, आदि चलाएं)
  • यदि डेटाबेस बनाया गया है, तो यह वापस लौटाएगा कि स्कीमा कितने संशोधन हुए हैं। यह मान दिलचस्प नहीं हो सकता है, लेकिन यह शून्य नहीं है।
  • यदि फ़ाइल मौजूद है और डेटाबेस (या खाली नहीं) है, तो आपको एक त्रुटि मिलेगी।

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

integrity_check से बचें। यह न केवल प्रत्येक पृष्ठ की जांच करता है, बल्कि फिर इंडेक्स के खिलाफ तालिकाओं की सामग्री को सत्यापित करता है। यह एक बड़े डेटाबेस पर सकारात्मक हिमनद है।

+1

"प्राग्मा schema_version;" कई बार त्रुटि "डेटाबेस लॉक" फेंकता है। मैं "pragma quick_check" दूंगा; एक प्रयास –

+1

यदि आपका डेटाबेस लॉक है, तो यह लॉक है। सब कुछ असफल हो जाएगा। लॉक होने पर पुनः प्रयास करें। :) –

+0

आप सही हैं। डेटाबेस लॉक होने पर सब कुछ विफल हो जाता है। यहां तक ​​कि चयन करता है। मेरे मामले में मैं यह निर्धारित करना चाहता था कि फ़ाइल एक स्क्लाइट 3 डेटाबेस था या नहीं। अगर मुझे "डेटाबेस लॉक किया गया है" त्रुटि मिलती है तो मुझे लगता है कि यह फ़ाइल सुरक्षित है कि फ़ाइल एक स्क्लाइट 3 डेटाबेस है। –

2

मुझे लगता है कि एक प्रामाणिक integrity_check ऐसा कर सकता है।

+0

चेतावनी दी जानी चाहिए; यदि आपका डेटाबेस बड़ा है तो यह बहुत धीमा हो सकता है। –

4

सी # में ऐसा करने की आवश्यकता होगी, किसी को भी System.Data.SQLite साथ आप तुरंत एक लेन-देन शुरू कर सकते हैं, और फिर इसे वापस रोल के रूप में इस के लिए: -

private bool DatabaseIsValid(string filename) 
    { 
     using (SQLiteConnection db = new SQLiteConnection(@"Data Source=" + filename + ";FailIfMissing=True;")) 
     { 
      try 
      { 
       db.Open(); 
       using (var transaction = db.BeginTransaction()) 
       { 
        transaction.Rollback(); 
       } 
      } 
      catch (Exception ex) 
      { 
       log.Debug(ex.Message, ex); 
       return false; 
      } 
     } 
     return true; 
    } 

तो फ़ाइल एक वैध डेटाबेस नहीं है निम्नलिखित SQLiteException फेंक दिया गया है - फ़ाइल एन्क्रिप्टेड है या डेटाबेस नहीं है (System.Data.SQLite.SQLiteErrorCode.NotADb)। यदि आप एन्क्रिप्टेड डेटाबेस का उपयोग नहीं कर रहे हैं तो यह समाधान पर्याप्त होना चाहिए। (केवल 'db.Open()' सिस्टम के संस्करण 1.0.81.0 के लिए आवश्यक था। डेटा। SQLite लेकिन जब मैं संस्करण 1.0.91.0 में अपग्रेड किया गया तो मुझे इसे काम करने के लिए आंतरिक उपयोग ब्लॉक को डालना पड़ा)।

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