অ্যান্ড্রয়েড এসকিউএল ডাটাবেসে কোনও টেবিল বিদ্যমান কিনা তা কীভাবে চেক করা যায়?


87

আমার কাছে একটি অ্যান্ড্রয়েড অ্যাপ রয়েছে যা ডাটাবেসে ইতিমধ্যে কোনও রেকর্ড রয়েছে কিনা তা যাচাই করা দরকার এবং যদি না হয় তবে কিছু জিনিস প্রক্রিয়া করুন এবং শেষ পর্যন্ত এটি সন্নিবেশ করান এবং ডেটাবেস থেকে ডেটা উপস্থিত থাকলে কেবল ডাটা পড়ুন। আমি এসকিউএলডিপ ডাটাবেসটির পুনর্লিখনযোগ্য উদাহরণটি তৈরি করতে ও পেতে এসকিউএলইটওপেনহেল্পারের একটি সাবক্লাস ব্যবহার করছি, যা আমি ভেবেছিলাম যে টেবিলটি ইতিমধ্যে উপস্থিত না থাকলে স্বয়ংক্রিয়ভাবে যত্ন নিয়েছে (যেহেতু কোডটি অনক্রিয়েটে রয়েছে সেহেতু (... ) পদ্ধতি)।

যাইহোক, যখন টেবিলটি এখনও উপস্থিত নেই এবং আমার কাছে থাকা প্রথম এসকিউএলডিটি ডাটাবেস অবজেক্টটির উপর প্রথম পদ্ধতিটি জিজ্ঞাসা করা কল (...), আমার লগক্যাটটি "I / ডাটাবেস (26434)" এর ত্রুটি দেখায়: স্ক্লাইটটি ফিরে এসেছে: ত্রুটি কোড = 1, # = তেমন কোনও টেবিল নেই: অ্যাপডাটা ", এবং যথেষ্ট পরিমাণে নিশ্চিত, অ্যাপডেটা সারণী তৈরি হচ্ছে না।

কেন কোন ধারণা?

আমি টেবিলের উপস্থিতি আছে কিনা তা পরীক্ষা করার জন্য একটি পদ্ধতির সন্ধান করছি (কারণ এটি যদি না থাকে তবে ডেটা অবশ্যই এতে থাকে না, এবং আমি এটি না লিখে যতক্ষণ না টেবিলটি তৈরি হয় মনে হয় এটি পড়ার দরকার নেই) সঠিকভাবে), বা এটি তৈরি হয়েছে কিনা তা নিশ্চিত করার একটি উপায় এবং ঠিক খালি, সময়টিতে প্রথম প্রশ্নের জন্য ক্যোয়ারী (...)

সম্পাদনা
নীচে দুটি উত্তর পরে এটি পোস্ট করা হয়েছিল:
আমি মনে করি আমি সম্ভবত সমস্যাটি খুঁজে পেয়েছি। আমি কোনও কারণে সিদ্ধান্ত নিয়েছি যে উভয়ই একই ডাটাবেস ফাইলে অ্যাক্সেস সত্ত্বেও, প্রতিটি টেবিলের জন্য একটি আলাদা এসকিউএলওপেনহেল্পার তৈরি করার কথা ছিল। আমি মনে করি যে কেবলমাত্র একটি ওপেনহেল্পার ব্যবহার করার জন্য সেই কোডটিকে পুনরায় সজ্জিত করা এবং এর অনক্রিয়েটের ভিতরে উভয় টেবিল তৈরি করা আরও ভাল কাজ করতে পারে ...

উত্তর:


127

আর একবার চেষ্টা কর:

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();
স্টাইলার 1972 21

4
অজানা কারণে, টেবিলের নামটি সংবেদনশীল। আমি বরং ব্যবহার করিselect * from sqlite_master where UPPER(name) = 'ROUTES'.
Thupten

4
উত্তম উত্তর কিন্তু ব্যথার ব্যাকরণ! অবশ্যই 'isTableExisting ()' বলা উচিত।
ক্রিস হ্যাটন

4
এটি আমার পক্ষে কাজ করেছে তবে আমাকে কোয়েরিটি একটি চেষ্টা / ক্যাপচারে আবদ্ধ করতে হয়েছিল বা টেবিলটি উপস্থিত না থাকলে আমার অ্যাপ্লিকেশনটি ক্র্যাশ হয়ে যায়।
ব্র্যাডেন হোল্ট

52

আমি অ্যান্ড্রয়েড এসকিউএলআইপি এপিআই সম্পর্কে কিছুই জানি না তবে আপনি যদি সরাসরি এসকিউএলে এটির সাথে কথা বলতে সক্ষম হন তবে আপনি এটি করতে পারেন:

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

যা নিশ্চিত করে যে সারণী সর্বদা তৈরি হয়েছে এবং যদি ইতিমধ্যে বিদ্যমান থাকে তবে কোনও ত্রুটি নিক্ষেপ করবে না।


এসকিউএলইটওয়েলহেল্পার ক্লাসের মধ্যেই আমি অনক্রিট পদ্ধতিতে টেবিলটি তৈরি করছি। অ্যান্ড্রয়েডে, সেই শ্রেণিকে টেবিলটি তৈরি করতে দেওয়া উচিত, কারণ এটি অ্যাপটিকে তার ডাটাবেসটি স্বয়ংক্রিয়ভাবে আপডেট করতে দেয় এবং সাধারণভাবে দৃশ্যত আরও দক্ষ। দুর্ভাগ্যক্রমে, যে কোডব্লক কোডটি কার্যকর করে তার মতোই আপনি লিখেছেন সময় মতো দৌড়ায় না :(
ক্যাম্পারডেভ

এটি দুর্দান্ত কাজ করে এবং সূচির সাথেও কাজ করে, যেমন: "উপস্থিত না থাকলে সূচক তৈরি করুন [...]"।
এরিক ফরটিয়ার

4
এটি আসলে জিজ্ঞাসিত প্রশ্নের সেরা উত্তর।
আসল অ্যান্ড্রয়েড

4
তবে প্রশ্নটি একটি তৈরি করতে
বলছে

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.
    }
}

এটা আমার জন্য কাজ!


4
যদি () ব্লকের ভিতরে লগ স্টেটমেন্টটি রাখা ভাল হয় না? দেখে মনে হচ্ছে যদি এসকিউএলএক্সেপশনটি "এরকম কোনও টেবিল নয়" এর চেয়ে অন্য কারণে ছুঁড়ে ফেলা হয়, লগটি ইঙ্গিত দেয় যে আপনি টেবিলটি তৈরি করছেন, যখন আপনি আসলে নন।

4
প্রবাহ নিয়ন্ত্রণ করতে ব্যাতিক্রম ব্যবহার করা লজ্জাজনক এমন কিছু যা অন্যকে শেখানো হয় না। এই ফ্যাশনে বার্তাটি চেক করা, দ্বিগুণ তাই।
নিক কার্ডোসো

যদি অল্প পরিমাণে ব্যবহার করা হয়, তবে আমি মনে করি না যে উপরে বর্ণিত হিসাবে ব্যবহারের ক্ষেত্রে ব্যতিক্রমগুলি ব্যবহার করে কিছু ভুল আছে। অবশ্যই আমি কিছুতেই লজ্জা পাচ্ছি না।
রোবগুইনেস

আমি মনে করি 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পরিবর্তে method পদ্ধতিটি ডাকা হচ্ছে কিনা । যদি তা হয় তবে ডাটাবেসের সংস্করণ নম্বরটি কোনও এক সময় পরিবর্তিত হয়েছিল কিন্তু যখন ঘটেছিল তখন সারণিটি কখনই সঠিকভাবে তৈরি করা যায় নি।

একদিকে যেমন, আপনি এটির সাথে সমস্ত সংযোগ বন্ধ রয়েছে এবং কল করে Context#deleteDatabaseএবং তারপরে SQLiteOpenHelperআপনাকে একটি নতুন ডিবি অবজেক্ট দেওয়ার জন্য এটি ব্যবহার করে ডাটাবেসটির বিনোদনকে জোর করতে পারেন ।


ঠিক আছে, আমি getWritableDat database () কলের মাধ্যমে আমার ডাটাবেস অবজেক্টটি পাচ্ছি, দুঃখিত আমি তা উল্লেখ করতে ভুলে গিয়েছি। এছাড়াও, আমি নিশ্চিত অনআপগ্রেড () কল করা হচ্ছে না, যেহেতু সেই পদ্ধতিতে একটি লগ.ড (...) কল রয়েছে যার প্রথম লাইন যা আমি ডাটাবেসে দেখছি না। আমি পুরো ডাটাবেস ফাইলটি মুছে ফেলার চেষ্টা করব, এবং আমরা তা দেখতে পাব যে এটি
কোনওরকমভাবে

দুর্ভাগ্যক্রমে, পুরো ডাটাবেস মুছে ফেলার (আমি ফাইলটি মুছে ফেলার জন্য রুট এক্সপ্লোরার ব্যবহার করেছি) কাজ করেনি। আমি আমার অ্যাপ্লিকেশনটিতে দুটি টেবিল ব্যবহার করি - এর মধ্যে একটি পুরোপুরি পুরোপুরি শুরু হয়েছিল, তবে অন্যটি যা আমাকে সমস্ত সমস্যা দিয়ে চলেছে তা করেনি।
ক্যাম্পারডেভ

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 ডাটাবেসে সমস্ত সারণী এবং সূচিগুলির তথ্য সম্বলিত স্ক্লাইট_মাস্টার সারণী বজায় রাখে।
  • সুতরাং এখানে আমরা এটিতে কেবল নির্বাচন কমান্ড চালিয়ে যাচ্ছি, আমরা সারণী উপস্থিত থাকলে 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

গুরুত্বপূর্ণ শর্তটি যদি চেক টেবিলটি উপস্থিত না থাকে তবে ডাটাবেসে টেবিলটি ইতিমধ্যে বিদ্যমান রয়েছে

মত ...

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

..... টোস্ট টি = টোস্ট.মেকটেক্সট (প্রসঙ্গ, "চেষ্টা করুন ...", টোস্ট.এলএনজিএইচথএসএইচআরটি); 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

.....

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.