एंड्रॉइड SQLite डेटाबेस में एक टेबल मौजूद होने पर कोई कैसे जांचता है?


87

मेरे पास एक एंड्रॉइड ऐप है जो यह जांचने की आवश्यकता है कि क्या डेटाबेस में पहले से ही एक रिकॉर्ड है, और यदि नहीं, तो कुछ चीजों को संसाधित करें और अंततः इसे डालें, और यदि डेटा मौजूद है तो बस डेटाबेस से डेटा पढ़ें। मैं बनाने के लिए SQLiteOpenHelper का एक उपवर्ग उपयोग कर रहा हूं और SQLiteDatabase का एक पुन: लिखने योग्य उदाहरण प्राप्त करने के लिए, जो मुझे लगा कि स्वचालित रूप से तालिका बनाने का ख्याल रखा गया है अगर यह पहले से मौजूद नहीं था (कोड करने के लिए जो ऑनक्रिएट में है ... ) तरीका)।

हालाँकि, जब तालिका अभी तक मौजूद नहीं है, और पहली विधि SQLiteDatabase ऑब्जेक्ट पर है जो मेरे पास क्वेरी (...) के लिए कॉल है, तो मेरा लॉगकैट "I / डेटाबेस (26434) की त्रुटि दिखाता है: sqlite लौटा: त्रुटि" कोड = 1, msg = ऐसी कोई तालिका नहीं: appdata ", और निश्चित रूप से पर्याप्त है, appdata तालिका नहीं बनाई जा रही है।

कोई विचार क्यों?

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

EDIT
यह नीचे दो उत्तरों के बाद पोस्ट किया गया था:
मुझे लगता है कि मुझे समस्या मिल सकती है। मैंने किसी कारण से फैसला किया कि प्रत्येक तालिका के लिए एक अलग SQLiteOpenHelper बनाया जाना चाहिए था, भले ही दोनों एक ही डेटाबेस फ़ाइल तक पहुँचते हों। मुझे लगता है कि उस कोड को केवल एक OpenHelper का उपयोग करना, और इसके अंदर दोनों तालिकाओं को बनाने से बेहतर काम हो सकता है ...

जवाबों:


126

इसको आजमाओ:

public boolean isTableExists(String tableName, boolean openDb) {
    if(openDb) {
        if(mDatabase == null || !mDatabase.isOpen()) {
            mDatabase = getReadableDatabase();
        }

        if(!mDatabase.isReadOnly()) {
            mDatabase.close();
            mDatabase = getReadableDatabase();
        }
    }

    String query = "select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'";
    try (Cursor cursor = mDatabase.rawQuery(query, null)) {
        if(cursor!=null) {
            if(cursor.getCount()>0) {
                return true;
            }
        }
        return false;
    }
}

इसके लिए बहुत धन्यवाद। बहुत अच्छा काम करता है। +1
ग्रे

11
मत भूलनाcursor.close();
styler1972

1
अज्ञात कारण के लिए, टैब्लेमनाम संवेदनशील है। बल्कि मैं उपयोग करता हूंselect * from sqlite_master where UPPER(name) = 'ROUTES'.
थुप्टेन

4
अच्छा जवाब लेकिन दर्दनाक व्याकरण! निश्चित रूप से 'TTableExisting ()' कहा जाना चाहिए।
क्रिस हैटन

1
यह मेरे लिए काम करता है लेकिन मुझे एक कोशिश / कैच में क्वेरी को लपेटना पड़ता है या जब टेबल मौजूद नहीं था तो मेरा ऐप क्रैश हो जाएगा।
ब्रैडन होल्ट

52

मुझे Android SQLite API के बारे में कुछ नहीं पता है, लेकिन अगर आप इसे सीधे SQL में बात करने में सक्षम हैं, तो आप ऐसा कर सकते हैं:

create table if not exists mytable (col1 type, col2 type);

जो यह सुनिश्चित करेगा कि तालिका हमेशा बनाई गई है और पहले से मौजूद होने पर कोई त्रुटि नहीं है।


यह है कि मैं SQLiteOpenHelper वर्ग के अंदर onCreate पद्धति में तालिका बना रहा हूं। एंड्रॉइड में, उस वर्ग को तालिका बनाने देने की सिफारिश की जाती है, क्योंकि यह ऐप को अपने डेटाबेस को स्वचालित रूप से अपडेट करने की अनुमति देता है, और बस सामान्य रूप से अधिक कुशल है। दुर्भाग्य से, वह कोडब्लॉक जो कोड को निष्पादित करता है जैसे आपने जो लिखा है वह समय पर नहीं चल रहा है :(
camperdave

यह महान काम करता है और इंडेक्स के साथ भी काम करता है, अर्थात: "इंडेक्स बनाएं यदि मौजूद नहीं है [...]"।
एरिक फोर्टियर

5
यह वास्तव में पूछे गए सवाल का सबसे अच्छा जवाब है।
मूल Android

1
लेकिन सवाल
10101010

12

हालाँकि इस प्रश्न के कई अच्छे उत्तर पहले से ही हैं, मैं एक और समाधान के साथ आया हूं जो मुझे लगता है कि अधिक सरल है। एक कोशिश ब्लॉक और निम्नलिखित कैच के साथ अपनी क्वेरी को घेरें:

catch (SQLiteException e){
    if (e.getMessage().contains("no such table")){
            Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" );
            // create table
            // re-run query, etc.
    }
}

यह मेरे लिए काम किया!


1
अगर () ब्लॉक के अंदर लॉग स्टेटमेंट डालना बेहतर नहीं होगा? ऐसा लगता है कि अगर SQLiteException को "इस तरह की कोई तालिका नहीं" के अलावा किसी अन्य कारण से फेंक दिया जाता है, तो लॉग इंगित करेगा कि आप तालिका बना रहे हैं, जबकि आप वास्तव में नहीं हैं।

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

यदि संयम से उपयोग किया जाता है, तो मुझे नहीं लगता कि उपयोग किए गए मामलों में अपवादों का उपयोग करने के साथ कुछ भी गलत है जैसे कि ऊपर वर्णित है। निश्चित रूप से कुछ भी नहीं, मुझे शर्म आती है।
रॉबगिननेस

मुझे लगता e.getMessage().contains("no such table")है कि नियंत्रण प्रवाह के अपवादों का उपयोग करने से भी बदतर है। दोनों खराब शैली है, लेकिन विशिष्ट पाठ के लिए त्रुटि संदेश पार्स करना बहुत खराब शैली है।
jox

11

यह जो मैंने किया है:

/* open database, if doesn't exist, create it */
SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null);

Cursor c = null;
boolean tableExists = false;
/* get cursor on it */
try
{
    c = mDatabase.query("tbl_example", null,
        null, null, null, null, null);
        tableExists = true;
}
catch (Exception e) {
    /* fail */
    Log.d(TAG, tblNameIn+" doesn't exist :(((");
}

return tableExists;

8

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


2

आपने उल्लेख किया है कि आपने एक वर्ग बनाया है जो विधि का विस्तार SQLiteOpenHelperऔर कार्यान्वयन करता onCreateहै। क्या आप यह सुनिश्चित कर रहे हैं कि आप अपने सभी डेटाबेस को उस वर्ग के साथ कॉल प्राप्त कर रहे हैं? आपको केवल SQLiteDatabaseवस्तुओं के माध्यम से होना चाहिए SQLiteOpenHelper#getWritableDatabaseऔर getReadableDatabaseअन्यथा onCreateआवश्यक होने पर विधि को नहीं बुलाया जाएगा। यदि आप ऐसा कर रहे हैं, तो पहले से ही देखें और देखें कि क्या वेंSQLiteOpenHelper#onUpgrade विधि को इसके बजाय बुलाया जा रहा है। यदि ऐसा है, तो डेटाबेस वर्जन नंबर को किसी समय पर बदल दिया गया था लेकिन ऐसा होने पर तालिका कभी ठीक से नहीं बनाई गई थी।

एक तरफ के रूप में, आप डेटाबेस के मनोरंजन को सुनिश्चित कर सकते हैं कि यह सुनिश्चित कर लें कि सभी कनेक्शन बंद हैं और कॉल कर रहे हैं Context#deleteDatabaseऔर फिर SQLiteOpenHelperआपको एक नई डीबी ऑब्जेक्ट देने के लिए उपयोग कर रहे हैं।


खैर, मैं अपने डेटाबेस ऑब्जेक्ट getWritableDatabase () कॉल के माध्यम से प्राप्त कर रहा हूं, माफ करना मैं इसे निर्दिष्ट करना भूल गया। इसके अलावा, मुझे यकीन है कि onUpgrad () को कॉल नहीं किया जा रहा है, क्योंकि उस विधि में एक Log.d (...) कॉल है जो इसकी पहली पंक्ति है जिसे मैं डेटाबेस में नहीं देख रहा हूं। मैं पूरे डेटाबेस फ़ाइल को हटाने की कोशिश करूँगा, और हम देखेंगे कि अगर यह किसी तरह से इसे ठीक करता है ...
Camperdave

दुर्भाग्य से, पूरे डेटाबेस को हटाने (मैंने फ़ाइल को शुद्ध करने के लिए रूट एक्सप्लोरर का उपयोग किया) काम नहीं किया। मैं अपने ऐप में दो तालिकाओं का उपयोग करता हूं - उनमें से एक को पूरी तरह से इनिशियलाइज़ किया गया है, हालाँकि दूसरा जो मुझे परेशान कर रहा है, वह नहीं है।
कैम्परडेव

2
 // @param db, readable database from SQLiteOpenHelper

 public boolean doesTableExist(SQLiteDatabase db, String tableName) {
        Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);

    if (cursor != null) {
        if (cursor.getCount() > 0) {
            cursor.close();
            return true;
        }
        cursor.close();
    }
    return false;
}
  • sqlite डेटाबेस में सभी तालिकाओं और अनुक्रमितों की जानकारी युक्त sqlite_master तालिका रखता है।
  • तो यहाँ हम केवल उस पर SELECT कमांड चला रहे हैं, अगर टेबल मौजूद है तो हमें 1 की गिनती वाले कर्सर मिलेंगे।

0
 public boolean isTableExists(String tableName) {
    boolean isExist = false;
    Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
    if (cursor != null) {
        if (cursor.getCount() > 0) {
            isExist = true;
        }
        cursor.close();
    }
    return isExist;
}

0

no such table exists: error आ रहा है क्योंकि एक बार जब आप एक तालिका के साथ डेटाबेस बनाते हैं उसके बाद जब भी आप उसी डेटाबेस में तालिका बनाते हैं तो यह त्रुटि देता है।

इस त्रुटि को हल करने के लिए आपको नया डेटाबेस बनाना होगा और ऑनक्रिएट () विधि के अंदर आप एक ही डेटाबेस में कई टेबल बना सकते हैं।


0

महत्वपूर्ण शर्त IF IF EXISTS नहीं है चेक-इन तालिका के पहले से मौजूद नहीं है या डेटाबेस में मौजूद नहीं है

पसंद...

String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "("
            + KEY_PLAYER_ID + " TEXT,"
            + KEY_PLAYER_IMAGE + " TEXT)";
db.execSQL(query);

0

मैंने उस का सामना किया और इसे पकड़ने की कोशिश के रूप में के रूप में सरल के रूप में कि मैं क्या मैं तालिका में चाहते हैं अगर यह मौजूद नहीं है त्रुटि का कारण होगा तो अपवादों से इसे पकड़ने और इसे बनाने :)

SQLiteDatabase db=this.getWritableDatabase();
        try{
            db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
            db.execSQL("DELETE FROM vacations");
        }catch (SQLiteException e){
            db.execSQL("create table o_vacations (id integer primary key ,name text ,vacation text,date text,MONTH text)");
            db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
            db.execSQL("DELETE FROM vacations");
        }


-1

..... Toast t = Toast.makeText (प्रसंग, "कोशिश ...", Toast.LENGTH_SHORT); t.show ();

    Cursor callInitCheck = db.rawQuery("select count(*) from call", null);

    Toast t2a = Toast.makeText(context, "count rows " + callInitCheck.getCount() , Toast.LENGTH_SHORT);
    t2a.show();

    callInitCheck.moveToNext();
    if( Integer.parseInt( callInitCheck.getString(0)) == 0) // if no rows then do
    {
        // if empty then insert into call

.....

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.