2011-04-27 13 views
23

मैं एक असली डिवाइस पर अपने आवेदन डिबग करने के लिए कोशिश कर रहा हूँ, लेकिन मैं इस त्रुटि मिलती है:java.lang.IllegalArgumentException: स्तंभ '_ id' मौजूद नहीं है

ERROR/AndroidRuntime(981): Caused by: java.lang.IllegalArgumentException: column '_id' does not exist

जब मैं एक एमुलेटर पर परीक्षण कर रहा हूँ, त्रुटि प्रकट नहीं होती है। त्रुटि निम्न कोड की अंतिम पंक्ति में दिया जाता है:

adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] { 
      DataHandlerDB.CONTACT_NAME_COL, 
      DataHandlerDB.CONTACT_NUMBER_COL, 
      DataHandlerDB.CONTACT_DURATION_COL, 
      DataHandlerDB.CONTACT_DATE_COL }, new int[] { 
      R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date }); 

यहाँ मेरी गतिविधि है:

public class MyActivity extends Activity { 

    private static final String LOG_TAG = "MyActivity"; 
    private ListView listview; 
    private SimpleCursorAdapter adapter;   
    private DataHandlerDB handler; 
    private SQLiteDatabase db; 
    private OpenHelper helper; 
    private Cursor c; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.main); 

     helper = new OpenHelper(this); 
     db = helper.getWritableDatabase(); 
     helper.onCreate(db); 
     setBasicContent(); 
     c.close(); 
    } 


    @Override 
    public void onDestroy(){ 

     super.onDestroy(); 
     DataHandlerDB.makeTheSelection(this).close(); 
     db.close(); 
     helper.close(); 

    } 

    @Override 
    public void onPause(){ 

     super.onPause(); 
     DataHandlerDB.makeTheSelection(this).close(); 
     db.close(); 
     helper.close(); 

    } 

    @Override 
    public void onStop(){ 

     super.onStop(); 
     DataHandlerDB.makeTheSelection(this).close(); 
     db.close(); 
     helper.close(); 

    } 


    @Override 
    protected void onResume(){ 

     super.onResume(); 
     setBasicContent(); 

    } 

    public void setBasicContent() { 

     listview = (ListView) findViewById(R.id.list_view); 

     Log.i(LOG_TAG, "listview " + listview); 

     c = DataHandlerDB.makeTheSelection(this); 

     c.moveToFirst(); 

     if(db.isOpen()) 
      Log.i(LOG_TAG, "db is opened"); 

     Log.i(LOG_TAG, "cursor: " + c.getCount()); 

     startManagingCursor(c); 

     adapter = new SimpleCursorAdapter(this, R.layout.list_item, c, new String[] { 
       DataHandlerDB.CONTACT_NAME_COL, 
       DataHandlerDB.CONTACT_NUMBER_COL, 
       DataHandlerDB.CONTACT_DURATION_COL, 
       DataHandlerDB.CONTACT_DATE_COL }, new int[] { 
       R.id.contact_name, R.id.phone_number, R.id.duration, R.id.date }); 

     Log.i(LOG_TAG, "before setAdapter"); 
     Toast.makeText(this, "Before setAdapter", Toast.LENGTH_SHORT).show(); 

     listview.setAdapter(adapter); 

     db.close(); 

     if(db.isOpen()){ 

      Log.i(LOG_TAG, "db is opened."); 

     } 

     if(!c.isClosed()){ 

      Log.i(LOG_TAG, "cursor is opened"); 

     }   
    }  
} 

समारोह है कि प्रश्नों और रिटर्न Cursor वर्ग DataHandlerDB में है:

public class DataHandlerDB { 

private static final String DATABASE_NAME = "calls.db"; 
private static final int DATABASE_VERSION = 1; 

protected static String CONTACT_NAME_COL = "contact_name"; 
protected static String CONTACT_NUMBER_COL = "contact_number"; 
protected static String CONTACT_DURATION_COL = "duration"; 
protected static String CONTACT_DATE_COL = "date"; 
protected static String CONTACT_MONTH_COL = "month"; 

// create the DB 
public static SQLiteDatabase createDB(Context ctx) { 
    OpenHelper helper = new OpenHelper(ctx); 
    SQLiteDatabase db = helper.getWritableDatabase(); 
    helper.onCreate(db); 
    helper.onOpen(db); 
    db.close(); 
    return db; 
} 

public static Cursor makeTheSelection(Context ctx) { 

    OpenHelper helper = new OpenHelper(ctx); 
    SQLiteDatabase db = helper.getWritableDatabase(); 

    Cursor cursor = db.query(TABLE_NAME_2, null, null, null, null, null, 
      "duration desc"); 

    cursor.moveToFirst(); 
    db.close(); 

    return cursor; 
} 
    // class OpenHelper 
public static class OpenHelper extends SQLiteOpenHelper { 

    private final Context mContext; 

    OpenHelper(Context context) { 

     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     this.mContext = context; 

    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.i(LOG_TAG, "entrou no onCreate"); 
     String[] sql = mContext.getString(
       R.string.MyAppDatabase_OnCreate).split("\n"); 

     db.beginTransaction(); 

     try { 
      execMultipleSQL(db, sql); 
      db.setTransactionSuccessful(); 
     } catch (SQLException e) { 

      Log.e("Error creating tables and debug data", e.toString()); 
      throw e; 

     } finally { 
      db.endTransaction(); 

     } 
    } 

    private void execMultipleSQL(SQLiteDatabase db, String[] sql) { 

     for (String s : sql) { 

      if (s.trim().length() > 0) { 

       db.execSQL(s); 
      } 
     } 

    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 

     Log.w("MyDB Database", 
     "Upgrading database, this will drop tables and recreate."); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); 

    } 

    @Override 
    public void onOpen(SQLiteDatabase db) { 

     super.onOpen(db); 
    } 
} 
} 

एसक्यूएल कमांड के साथ एक्सएमएल फ़ाइल है:

<string name="MyAppDatabase_OnCreate"> 
    "CREATE TABLE IF NOT EXISTS contact_data(_id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, duration_sum TIME, date DATE, current_time TIME, cont INTEGER, type VARCHAR, month VARCHAR(50), day VARCHAR(50), year VARCHAR(50));" 
</string> 

मुझे लगता है कि एप्लिकेशन पहली बार शुरू होने पर डेटाबेस नहीं बना रहा है। मुझे ऐसा लगता है क्योंकि यह कॉलम _id पा सकता है, लेकिन इसे _id कॉलम के साथ बनाने के लिए एक्सएमएल कोड में स्पष्ट रूप से लिखा गया है। मुझे यह भी लगता है कि क्योंकि मैंने _id सहित SELECT विधि में कॉलम स्पष्ट रूप से लिखे हैं। मैं इसे इस तरह से किया था:

Log.i(LOG_TAG, "Cursor(0)" + cursor.getColumnName(0)); 
:

Caused by: android.database.sqlite.SQLiteException: no such column: _id: , while compiling: SELECT _id, contact_id, contact_name, number_type, contact_number, duration, duration_sum, date, current_time, cont, type, month, day, year FROM contact_data ORDER BY duration desc

मैं तो जैसे डेटाबेस के पहले कॉलम में लॉग इन किया है:

Cursor cursor = db.query(TABLE_NAME_2, 
       new String[]{ 
       "_id", 
       "contact_id", 
       "contact_name", 
       "number_type", 
       "contact_number", 
       "duration", 
       "duration_sum", 
       "date", 
       "current_time", 
       "cont", "type", 
       "month", 
       "day", 
       "year"}, null, null, null, null, 
       "duration desc"); 

इस मामले में, त्रुटि मैं प्राप्त लगभग एक ही है

यह id मुद्रित किया गया, _id नहीं। जैसा कि आप देख सकते हैं, कथन में _id लिखा गया है। इस समस्या को हल करने के बारे में कोई सुझाव?

+0

डिवाइस से पूरी तरह से ऐप को अनइंस्टॉल करें (उदा। सेटिंग्स> एप्लिकेशन> एप्लिकेशन प्रबंधित करें), और पुनः प्रयास करें। मुझे संदेह है कि आपका डेटाबेस पहले से ही '_id' कॉलम के बिना मौजूद है। – CommonsWare

+0

जैसा आपने कहा था मैंने किया लेकिन त्रुटि बनी हुई है। = ( – rogcg

उत्तर

37

आप कर्सर का उपयोग करने की कोशिश कर रहे हैं कि _id नामक कॉलम की आवश्यकता है। यह आपके टेबल निर्माण कथन को संपादित करने और _id नामक कॉलम जोड़ने के समान सरल है।

_id INTEGER PRIMARY KEY AUTOINCREMENT 

इस जोड़ें और आप तो इसका इस्तेमाल करने में सक्षम हो जाएगा:

इसके declartion कुछ इस तरह लग रहा है। मेरा मानना ​​है कि यह एक आवश्यकता है जिसे SimpleCursorAdapter का उपयोग करने के लिए आवश्यक है।

अद्यतन

"CREATE TABLE IF NOT EXISTS contact_data(_id INTEGER PRIMARY KEY AUTOINCREMENT, contact_id INTEGER, contact_name VARCHAR(50), number_type VARCHAR(50), contact_number VARCHAR(50), duration TIME, duration_sum TIME, date DATE, current_time TIME, cont INTEGER, type VARCHAR, month VARCHAR(50), day VARCHAR(50), year VARCHAR(50));" 

समाधान: '(' बाएं कोष्ठक के बीच एक रिक्ति जोड़ने के लिए और

+4

'कर्सर एडाप्टर' को हमेशा '_id' नामक कॉलम की आवश्यकता होती है। – surfer190

+1

आप इसे बनाने के बजाय उपनाम का उपयोग कर सकते हैं! अगर आपके पास पहले से ही आपका _id कॉलम है लेकिन इसका दूसरा नाम है, तो बस अपने प्राथमिक क्वेरी में AS का उपयोग करके अपना प्राथमिक कुंजी नाम बदलें: {Myprimarykey AS _id चुनें, तालिका से नाम जहां '% queryfilter%' नाम है;} – jcasadellaoller

9

मैं पड़ा है समान समस्या _ id क्योंकि मैं _ id जोड़ने नहीं किया गया था प्रक्षेपण तर्क के लिए कॉलम, इसलिए _id प्रोजेक्ट में जोड़ना प्रश्न के tions तर्क समाधान था।

String[] projections = {"_id", "name", "age"}; 

Cursor cursor = db.query(domainClass.getSimpleName(), projections, 
    null, null, null, null, null); 
+1

यह मेरे लिए समाधान था। मुझे मूर्खतापूर्ण। धन्यवाद। –

2

सबसे पहले इस ऐप्लिकेशन को अनइंस्टॉल, और उसके बाद निम्न चरणों:

  1. स्वच्छ परियोजना
  2. पुनर्निर्माण


    उदाहरण (@nobugs द्वारा टिप्पणी की) वह प्रोजेक्ट

  3. ऐप डीबग करें (Shift + F9)
संबंधित मुद्दे