2013-05-15 2 views
1

SQLite에서 실행되는 ContentProvider에서 _ID 자동 증가 열을 선언했지만 stacktrace에 다음과 같은 "_id"오류 메시지가 표시됩니다. 이 오류?SQLiteException : 해당 열 없음 : _id : ContentProvider 용

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 

다른 이상한 것은, 난 아무데도 내 코드에서 컨텐트 프로 클래스의 query 메소드를 호출하지 않았다 아직 내가 컨텐트 프로 클래스의이 쿼리 방법의 코드 선으로 오류의 위치를 ​​가지고 있다는 것입니다 컨텐트 프로의 쿼리 메소드를 호출 해되지 않는 경우는 스택 트레이스 나에게 오류의 위치를 ​​알려줍니다 어디 그러나 그것은 여기에,이다, 스택 트레이스에 안

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

컨텐트 프로 클래스 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); 

여기에 있습니다 : 그것은 내가 제거 또는 삭제 응용 프로그램에서 데이터를하고 내가 스택 트레이스에서 다른 오류를 가지고 있음을 한 후, 다시 실행하는 것이 제안 된 후, 여기있다 컨텐트 프로 클래스 여기

@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 

의 완전한 질의 방법은

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); 
    } 

} 
컨텐트 프로를 확장하는 ProviderExample 클래스의 코드를 더

여기에 테이블을 만드는 동안 난 당신이 실수를하고있는 생각 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); 
} 
} 
+0

앱을 다시 실행 –

+0

선택을 제거 다시 선택을 실행 + "_id ="+ uri.getLastPathSegment(); 선택 = 선택 + "_id =?"대신 + uri.getLastPathSegment(); 이런 식으로. – Harshid

+0

앱 데이터를 삭제하고 삭제했으며 다른 오류가 발생했습니다. stacktrace 결과를 표시하려면 내 질문에 EDIT 주석을 넣습니다. – Kevik

답변

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
@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);"); 
    } 

변경 제거 후 =

관련 문제