2010-03-05 13 views
7

मैंने अपना डेटाबेस फ़ील्ड "संपत्ति" फ़ोल्डर में रखा है। और डेटाबेस को "/ data/data/my_packname/डेटाबेस /" में कॉपी करने के लिए इस blog से कोड का उपयोग करें, (जब मैं इस ऐप को चलाता हूं तो यह इसे ऑनक्रेट() विधि में चलाता है) फिर चुनें * से चुनें। डेटा प्राप्त करने के लिए। लेकिन यह मुझे अपवाद देता है: ऐसी कोई तालिका नहीं।अपने स्वयं के एसक्लाइट डेटाबेस का उपयोग कैसे करें?

किसी ने मुझे बताया कि यदि मैं SQLiteOpenHelper के ऑनक्रेट() में फ़ाइल की प्रतिलिपि बनाने का प्रयास कर रहा हूं, तो यह बहुत देर हो चुकी है। तो प्रतिलिपि फ़ाइल कोड पूरी फ़ाइल की प्रतिलिपि नहीं बना सकता है।

तो मुझे डेटाबेस को पहले खींचने के लिए adb या ddms का उपयोग करने की आवश्यकता है?

तो, कोई भी मुझे अपने स्वयं के डेटाबेस का उपयोग करने के लिए सिखा सकता है? क्या आप मुझे सेटअप बता सकते हैं?

उत्तर

1

डेटाबेस कॉपी करने के बाद, आपको किसी भी क्वेरी को निष्पादित करने से पहले SQLiteDatabase ऑब्जेक्ट को बंद करने और फिर से खोलने का प्रयास करना चाहिए। मुझे एक इनपुट स्ट्रीम से डीबी की प्रतिलिपि बनाने में एक ही समस्या थी और यही कारण है कि यह मेरे लिए हल हो गया।

11

मैंने उस ब्लॉग पोस्ट में निर्देशों का उपयोग किया है और सही ट्रैक पर, SQLiteOpenHelper को अनावश्यक रूप से विस्तारित करके समस्या को गंभीर रूप से जटिल करने के लिए उन्हें पाया है। मैं काफी बेहतर भाग्य कर लिया है निम्नलिखित:

  1. एक उपयोगिता वर्ग है कि संपत्ति से सही निर्देशिका में कॉपी करके स्थिर डाटाबेस बनाता है, लेकिन नहीं मिलता है SQLiteOpenHelper निम्नलिखित पर ही तो काट दिया बनाएं प्रारूप।

  2. SQLiteDatabase.openDatabase()

संपादित का उपयोग करके डाटाबेस को खोलने के लिए एक ही उपयोगिता वर्ग का उपयोग करते हुए: यहाँ इस उपयोगिता वर्ग मेरे द्वारा बनाए गए का एक संस्करण है; यह बिल्कुल पूरा नहीं है, लेकिन आपको बहाव मिलेगा।

public class DbUtils { 
    private static final String DB_PATH = "/data/data/com.mypackage.myapp/databases/"; 
    private static final String DB_NAME = "my.db"; 

    public static void createDatabaseIfNotExists(Context context) throws IOException { 
     boolean createDb = false; 

     File dbDir = new File(DB_PATH); 
     File dbFile = new File(DB_PATH + DB_NAME); 
     if (!dbDir.exists()) { 
      dbDir.mkdir(); 
      createDb = true; 
     } 
     else if (!dbFile.exists()) { 
      createDb = true; 
     } 
     else { 
      // Check that we have the latest version of the db 
      boolean doUpgrade = false; 

      // Insert your own logic here on whether to upgrade the db; I personally 
      // just store the db version # in a text file, but you can do whatever 
      // you want. I've tried MD5 hashing the db before, but that takes a while. 

      // If we are doing an upgrade, basically we just delete the db then 
      // flip the switch to create a new one 
      if (doUpgrade) { 
       dbFile.delete(); 
       createDb = true; 
      } 
     } 

     if (createDb) { 
      // Open your local db as the input stream 
      InputStream myInput = context.getAssets().open(DB_NAME); 

      // Open the empty db as the output stream 
      OutputStream myOutput = new FileOutputStream(dbFile); 

      // transfer bytes from the inputfile to the outputfile 
      byte[] buffer = new byte[1024]; 
      int length; 
      while ((length = myInput.read(buffer)) > 0) { 
       myOutput.write(buffer, 0, length); 
      } 

      // Close the streams 
      myOutput.flush(); 
      myOutput.close(); 
      myInput.close(); 
     } 
    } 

    public static SQLiteDatabase getStaticDb() { 
     return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 
    } 
} 
+0

क्या आप उपयोगिता वर्ग साझा कर सकते हैं? क्योंकि मुझे यह समझ में नहीं आता है: "बहुत बहुत धन्यवाद – user275788

+0

मैंने अपनी उपयोगिता कक्षा का एक बहुत ही कम संस्करण जोड़ा है, बस वहां कोड का मांस छोड़ दिया है। (उदाहरण के लिए, मैं अत्यधिक लॉग स्टेटमेंट जोड़ने की सलाह देता हूं, लेकिन इस नमूना कोड के लिए ये आवश्यक नहीं हैं)। वैसे भी, कोड के इस संस्करण में, आपको केवल तब करना होगा जब एप्लिकेशन शुरू होता है, तो createDatabaseIfNotExists() को कॉल करें, जैसे कि आप android.app.Aplication में क्रिएट() पर विस्तार करते हैं। –

+0

यह भी ध्यान रखें कि यदि आपका फ़ाइल आकार 1 एमबी से अधिक पढ़ता है() फेंक IoException और संपत्ति लॉग "डेटा UNCOMPRESSED_DATA_MAX से अधिक है" ...मैंने अपनी फाइल का नाम देकर हल किया .jpg संपत्तियों में -> एपेट ने इसे संपीड़ित करने की कोशिश नहीं की – Mikpa

-1

लेख द्वारा पोस्ट की गई से डेटाबेस बनाने के रास्ते से थोड़ा अलग से है कि यह कैसे एंड्रॉयड उदाहरण में किया है (मैं नहीं चाहता कि अगर यह अच्छा है या बुरा है कहना चाहता हूँ) है।

मैं कैसे SDKs NotePad sample

यह अच्छा उदाहरण से शुरू करने के लिए है क्योंकि यह (यह वास्तव में db से डेटा प्राप्त करने का एकमात्र अच्छा तरीका है ContentProvider के माध्यम से दोनों डेटाबेस सृजन विषय और डेटाबेस का उपयोग को शामिल किया गया से डेटाबेस का उपयोग करने के सीखा है, अन्यथा आपके कोड के कई स्थानों से डेटा प्राप्त करने का प्रयास करते समय आपको समस्याएं आती हैं)।

आपको ध्यान रखना चाहिए कि SQLiteOpenHelper वास्तव में शक्तिशाली है और यदि आप इसे सही तरीके से उपयोग करेंगे तो "यह आपकी मदद करेगा"। उदाहरण के लिए यह वर्तमान डेटाबेस संस्करण (एसक्लाइट संस्करण नहीं है लेकिन डेटाबेस स्कीमा संस्करण के साथ आप जिस नंबर पर assingn संख्या) स्टोर करते हैं और जब आप नई डेटाबेस संरचना के साथ नया अनुप्रयोग संस्करण बनाते हैं तो आप वर्तमान स्कीमा को अद्यतन में नए संस्करण में अपडेट कर सकते हैं।

+0

मुझे नहीं लगता कि आप ब्लॉग पोस्ट के उद्देश्य को समझते हैं; नोटपैड नमूना * बनाने * डेटाबेस के लिए है, लेकिन प्रश्नकर्ता क्या करना चाहता है वह पूर्व-मौजूदा SQLite डीबी के आधार पर डिवाइस में डेटाबेस बना रहा है। –

+0

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

0

यहां "सिल्वियो डोनीनी" कोड से मेरा संस्करण है :), अब आप आसानी से डेटाबेस अपडेट कर सकते हैं।

private static final String DB_PATH = "/data/data/pakagename/databases/"; 
private static final String DB_NAME = "databaseName";  
private static SQLiteDatabase db; 

public static void createDatabaseIfNotExists(Context context,int version) throws IOException { 
    boolean createDb = false; 

    File dbDir = new File(DB_PATH); 
    File dbFile = new File(DB_PATH + DB_NAME); 
    if (!dbDir.exists()) { 
     dbDir.mkdir(); 
     createDb = true; 
    } 
    else if (!dbFile.exists()) { 
     createDb = true; 
    } 
    else { 
     // Check that we have the latest version of the db  
     db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 

     if (db.getVersion() != version) { 
      dbFile.delete(); 
      createDb = true; 
     } 

    } 

    if (createDb) { 

     // Open your local db as the input stream 
     InputStream myInput = context.getResources().openRawResource(R.raw.database); 

     // Open the empty db as the output stream 
     OutputStream myOutput = new FileOutputStream(dbFile); 

     // transfer bytes from the inputfile to the outputfile 
     byte[] buffer = new byte[1024]; 
     int length; 
     while ((length = myInput.read(buffer)) > 0) { 
      myOutput.write(buffer, 0, length); 
     } 

     // Close the streams 
     myOutput.flush(); 
     myOutput.close(); 
     myInput.close(); 
     SQLiteDatabase dbwrite = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READWRITE); 
     dbwrite.setVersion(version); 
     dbwrite.close(); 
     if (db != null) 
      db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 

    } 
} 

public static SQLiteDatabase getStaticDb() { 
    if (db != null) 
     return db; 

    return SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.OPEN_READONLY); 
} 
0

मुझे पता है कि यह एक पुराना सवाल है, लेकिन मैंने सभी उत्तरों की मदद से इसे समझने में बहुत समय लगाया।


समस्या यह है कि कोई डिवाइस अपने डेटा/डेटा /.../डेटाबेस फ़ोल्डर में डेटाबेस संग्रहीत करता है। इसलिए, जब आप डेटाबेस के बारे में sth बदलते हैं (नाम, एंड्रॉइड मेटाडेटा तालिका, आकार ..) संग्रहित डेटाबेस और मौजूदा डेटाबेस के लिए जाँच की गई विधि के कारण यह कोई फर्क नहीं पड़ता है।


नवीनतम डेटाबेस पाने के लिए, यह बदलने के बाद, आप मौजूदा databses के लिए जाँच के बिना कार्यक्रम चलाने चाहिए (उदा dbExist = checkDataBase(); के बजाय यह सिर्फ झूठे हैं)।

dbExist = checkDataBase(); 

बदलें:

dbExists = false; 

आप 'नई' databse आप मौजूदा जाँच पर लौट सकते हैं उठाया के बाद।

आशा है कि यह मदद करता है किसी को, दीना

0

मैं जानता हूँ कि यह एक पुरानी पोस्ट है, लेकिन जो लोग अभी भी एक Google या बिंग खोज के बाद यहां आने के लिए, यह कहा गया है समस्या का समाधान है:

CreateDataBase (0) में

निम्नलिखित जांच है;

this.getReadableDatabase(); 

वहाँ पहले से ही प्रदान की नाम के साथ एक डेटाबेस है और एक खाली डेटाबेस नहीं बनाता है, तो यह संपत्ति फ़ोल्डर में से एक के साथ ओवरराइट किया जा सकता ऐसी है कि अगर यह जाँच करता है। नए उपकरणों पर यह बेकार ढंग से काम करता है लेकिन कुछ ऐसे डिवाइस हैं जिन पर यह काम नहीं करता है। मुख्य रूप से पुराने उपकरण। मुझे बिल्कुल नहीं पता क्यों, लेकिन ऐसा लगता है कि getReadableDatabase() फ़ंक्शन न केवल डेटाबेस प्राप्त करता है बल्कि इसे खोलता है। यदि आप उस पर संपत्ति फ़ोल्डर से डेटाबेस की प्रतिलिपि बनाते हैं, तो उसके पास अभी भी एक खाली डेटाबेस के लिए सूचक है और आपको तालिका मिल जाएगी त्रुटियों में मौजूद नहीं है।

तो है ताकि इसे सभी उपकरणों पर काम आप निम्नलिखित लाइनों के लिए इसे संशोधित करना चाहिए बनाने के लिए: डेटाबेस की जांच में खोला जाता है

SQLiteDatabase db = this.getReadableDatabase(); 
if (db.isOpen()){ 
    db.close(); 
} 

यहां तक ​​कि अगर, यह उसके बाद बंद कर दिया है और यह आपको नहीं देंगे कोई और परेशानी

0

लोग शांत हो जाइए, के बाद लंबे शोध अंत में "ऐसी कोई तालिका" त्रुटि आस्तियों फ़ोल्डर में डेटाबेस का

चेक नाम अगर यह की तरह "DATABASE_NAME.EXTENSION" है तो विस्तार के साथ सहायक कक्षा में पूरा नाम डाल के लिए मूर्खतापूर्ण गलती पाया यह मेरी समस्या हल हो गई।

जैसे डेटाबेस के संपत्ति नाम में login.sqlite या login.db कुछ भी है। विस्तार से पूरी तरह से DB_NAME = login.sqlite डालें। this tutorial अब पूरी तरह से काम करता है।

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