SQLiteException:没有这样的列:_id:用于ContentProvider

时间:2013-05-15 04:06:11

标签: android sqlite android-contentprovider

我在SQLite上运行的ContentProvider中声明了_ID自动增量列,但是我在堆栈跟踪中得到以下“no such column:_id”错误消息,如何修复此错误?

 FATAL EXCEPTION: AsyncTask
 java.lang.RuntimeException: An error occured while executing doInBackground()
 Caused by: android.database.sqlite.SQLiteException: no such column: _id:,
 while compiling: SELECT _id, title, text FROM notes

另一个奇怪的事情是我没有在我的代码中的任何地方调用contentProvider类的查询方法,但是如果ContentProvider的查询,我在ContentProvider类的这个查询方法中得到了错误的位置作为一行代码方法没有被调用然后它不应该在堆栈跟踪中,但它是,它在这里告诉我堆栈跟踪中错误的位置

com.example.contentproviderexample.ProviderExample.query(ProviderExample.java:132)

ContentProvider类ProviderExample第132行

Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder);

编辑:在建议我从应用程序中卸载或删除数据并再次运行之后,在我这样做之后,我从堆栈跟踪中得到了一个不同的错误,这里是:

 Couldn't open notes.db for writing (will try read-only):
 android.database.sqlite.SQLiteException:
 AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY:
 , while compiling: CREATE TABLE IF NOT EXISTS
 notes (_id ID INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, text TEXT);

这是ContentProvider类的完整查询方法

 @Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    qb.setTables(TABLE_NAME);
    qb.setProjectionMap(notesProjectionMap);
         switch(sUriMatcher.match(uri)){
         case NOTES:
             break;
         case NOTES_ID:
             selection = selection + "_id=" + uri.getLastPathSegment();
             break;
         default:
             throw new IllegalArgumentException("Unknown URI" + uri);    
         }
         SQLiteDatabase db = dbHelper.getReadableDatabase();
         Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); // <-- no colunn _ID error here
         c.setNotificationUri(getContext().getContentResolver(), uri);
         return c

这里有更多来自ProviderExample类的代码,它扩展了ContentProvider

 public class ProviderExample extends ContentProvider {

public static final String DATABASE_NAME = "notes.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "notes";
public static final String AUTHORITY = "com.example.contentproviderexample.providerexample";
public static final UriMatcher sUriMatcher;
private static final int NOTES = 1;
private static final int NOTES_ID = 2;
private static HashMap<String, String> notesProjectionMap;

 static {
        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sUriMatcher.addURI(AUTHORITY, TABLE_NAME, NOTES);
        sUriMatcher.addURI(AUTHORITY, TABLE_NAME + "/#", NOTES_ID);
    }

 public static interface NoteItems extends BaseColumns {

        // notes in the CONTENT_URI is often plural where the actual table name is often singular version of this word
        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
        public static final String _ID = "_id";
        public static final String TITLE = "title";
        public static final String TEXT = "text";
        public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.example.providerexample";
        // static final String SINGLE_RECORD = "vnd.android.cursor.item/vnd.example.providerexample";
        public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.example.providerexample";
        // static final String MULTIPLE_RECORDS = "vnd.android.cursor.dir/vnd.example.providerexample"; 
        public static final String[] PROJECTION_ALL = {_ID, TITLE, TEXT};
        public static final String SORT_ORDER_DEFAULT = TITLE + " ASC";

 }

 private static class DatabaseHelper extends SQLiteOpenHelper{

     DatabaseHelper(Context context){
         super(context, DATABASE_NAME, null, DATABASE_VERSION);
     }

     @Override
     public void onCreate(SQLiteDatabase db) {
     db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + NoteItems._ID + " ID INTEGER PRIMARY KEY AUTOINCREMENT, " +  
             NoteItems.TITLE + " TEXT, " + NoteItems.TEXT + " TEXT);");
     }

     @Override
     public void onUpgrade(SQLiteDatabase db, int previousVersion, int newVersion) {
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
     onCreate(db);
     }

 }

private DatabaseHelper dbHelper;

@Override
public boolean onCreate() {
    dbHelper = new DatabaseHelper(getContext());
    return true;
}

@Override
public String getType(Uri uri) {
    switch (sUriMatcher.match(uri)){
        case NOTES:
            return NoteItems.CONTENT_TYPE;
        case NOTES_ID:
            return NoteItems.CONTENT_ITEM_TYPE;
        default:
            throw new IllegalArgumentException("Unknown URI" + uri);
    }

} 

这是MainActivity类

   public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks<Cursor>{

private SimpleCursorAdapter adapter;
private LoaderManager loaderManager;
private CursorLoader cursorLoader;
private ListView listView;
private int primaryKey;
private String primaryKeyString;
private String testTitle;
private String testText;
private static final int LOADER_ID = 1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    primaryKey = 0;
    testTitle = "test title";
    testText = "test text";

    ProviderExample providerExample = new ProviderExample();

    primaryKeyString = String.valueOf(primaryKey);
    getLoaderManager().initLoader(LOADER_ID, null, this);
    adapter = new SimpleCursorAdapter(this, R.layout.row_layout, null,
            new String[]{primaryKeyString, testTitle, testText}, new int[]{R.id.textView1, R.id.textView2, R.id.textView3},
            Adapter.NO_SELECTION);
    listView = (ListView) findViewById(R.id.listView1);
    listView.setAdapter(adapter);

    // load database with test values
    //loadDatabase();

}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String[] projection = {ProviderExample.NoteItems._ID, ProviderExample.NoteItems.TITLE, ProviderExample.NoteItems.TEXT };
    cursorLoader = new CursorLoader(this, ProviderExample.NoteItems.CONTENT_URI, projection, null, null, null);
    return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    adapter.swapCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    adapter.swapCursor(null);
}
 }

2 个答案:

答案 0 :(得分:1)

我认为在制作餐桌时你犯了一个错误。你alredy在引号内加了“ID”,你也有NoteItems._ID,这使得“_id ID”成为主要ID。所以你可能需要纠正它.. !!

 @Override
 public void onCreate(SQLiteDatabase db) {
 db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + NoteItems._ID + " ID INTEGER PRIMARY KEY AUTOINCREMENT, " +  
         NoteItems.TITLE + " TEXT, " + NoteItems.TEXT + " TEXT);");
 }

答案 1 :(得分:1)

@Override
     public void onCreate(SQLiteDatabase db) {
     db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" + NoteItems._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +  
             NoteItems.TITLE + " TEXT, " + NoteItems.TEXT + " TEXT);");
     }  

更改卸载后再次运行