Android-Spalte ‘_id’ existiert nicht?

Ich habe Probleme mit etwas, das im Notepad-Beispiel funktioniert. Hier ist der Code von NotepadCodeLab / Notepadv1Solution:

String[] from = new String[] { NotesDbAdapter.KEY_TITLE }; int[] to = new int[] { R.id.text1 }; SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to); 

Dieser Code scheint gut zu funktionieren. Aber um klar zu sein, ich habe das ADB- Dienstprogramm ausgeführt und SQLite 3 ausgeführt. Ich habe das Schema wie folgt untersucht:

sqlite> .schema

 CREATE TABLE android_metadata (locale TEXT); CREATE TABLE notes (_id integer primary key autoincrement, title text not null, body text not null); 

Alles scheint mir gut zu sein.


Nun zu meiner Bewerbung, die, soweit ich das beurteilen kann, mit ein paar kleinen Änderungen im Wesentlichen gleich ist. Ich habe meinen Code vereinfacht und vereinfacht, aber das Problem besteht weiterhin.

 String[] from = new String[] { "x" }; int[] to = new int[] { R.id.x }; SimpleCursorAdapter adapter = null; try { adapter = new SimpleCursorAdapter(this, R.layout.circle_row, cursor, from, to); } catch (RuntimeException e) { Log.e("Circle", e.toString(), e); } 

Wenn ich meine Anwendung ausführe, erhalte ich eine RuntimeException und die folgenden Ausgaben in LogCat von meiner Log.e() statement:

LogCat-Nachricht:

java.lang.IllegalArgumentException: Spalte ‘_id’ existiert nicht

Also zurück zu SQLite 3, um zu sehen, was sich an meinem Schema unterscheidet:

sqlite> .schema CREATE TABLE android_metadata (Gebietsschema TEXT); CREATE TABLE Kreise (_id Ganzzahl Primärschlüssel autoincrement, Sequenz Integer, Radius real, x real, y real);

Ich sehe nicht, wie ich das “_id” vermisse.

Was habe ich falsch gemacht?

Eine Sache, die zwischen meiner Anwendung und dem Notepad-Beispiel unterschiedlich ist, besteht darin, dass ich meine Anwendung von Grund auf mit dem Eclipse-Assistenten erstellte, während die Beispielanwendung bereits zusammengestellt wurde. Gibt es eine Art von Umgebungsänderung, die ich für eine neue Anwendung vornehmen muss, um eine SQLite-database zu verwenden?

Solutions Collecting From Web of "Android-Spalte ‘_id’ existiert nicht?"

Ich sehe, die Dokumentation für CursorAdapter besagt:

Der Cursor muss eine Spalte mit dem Namen _id oder diese class wird nicht funktionieren.

Der SimpleCursorAdapter ist eine abgeleitete class, daher scheint diese statement zu gelten. Die Aussage ist jedoch technisch falsch und für einen Neuling etwas irreführend. Die Ergebnismenge für den Cursor muss _id enthalten, nicht den Cursor selbst.
Ich bin mir sicher, dass dies einem DBA klar ist, weil diese Art von Kurzschrift für sie klar ist, aber für diese Neulinge führt die Unvollständigkeit der Aussage zu Verwirrung. Cursor sind wie Iteratoren oder pointers, sie enthalten nichts als einen Mechanismus zum Transversieren der Daten, sie enthalten selbst keine Spalten.

Die Loader-Dokumentation enthält ein Beispiel, in dem zu sehen ist, dass die _id im Projektionsparameter enthalten ist.

 static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS, Contacts.CONTACT_PRESENCE, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY, }; public Loader onCreateLoader(int id, Bundle args) { // ... return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); } 

Dies wurde beantwortet und ich möchte es hier ausführlicher machen.

SimpleCursorAdapter erfordert, dass die Ergebnismenge des Cursors eine Spalte mit dem Namen “_id” enthalten muss. Beeilen Sie sich nicht, das Schema zu ändern, wenn Sie die Spalte “_id” in Ihrer Tabelle nicht definiert haben. SQLite hat automatisch eine versteckte Spalte namens “rowid” für jede Tabelle hinzugefügt. Alles, was Sie tun müssen, ist, dass Sie einfach rowid explizit auswählen und als ‘_id’ Ex alias machen.

 SQLiteDatabase db = mHelper.getReadableDatabase(); Cursor cur = db.rawQuery( "select rowid _id,* from your_table", null); 

Tim Wus Code funktioniert wirklich …

Wenn Sie db.query verwenden, dann wäre es so …

 db.query(TABLE_USER, new String[] { "rowid _id", FIELD_USERNAME, }, FIELD_USERNAME + "=" + name, null, null, null, null); 

Was mein Problem mit diesem Fehler getriggers hat, war, dass ich die Spalte _id nicht in meine DB-Abfrage aufgenommen hatte. Das Hinzufügen hat mein Problem getriggers.

Ja, ich ändere auch die SELECT-String-Abfrage, um dieses Problem zu beheben.

 String query = "SELECT t.*,t.id as _id FROM table t "; 

Das ist wahrscheinlich nicht mehr relevant, aber ich habe heute dasselbe Problem. Bei Spaltennamen wird zwischen Groß- und Kleinschreibung unterschieden. Ich hatte eine _ID-Spalte, aber Android erwartet eine _id-Spalte.

Wenn Sie die Dokumentation von sqlite lesen, wird das Erstellen einer Spalte vom Typ INTEGER PRIMARY KEY intern die ROWID aliasieren, so dass es sich nicht lohnt, in jedem SELECT einen Alias ​​hinzuzufügen, der von allen üblichen Dienstprogrammen abweicht, die von etwas profitieren könnten eine Aufzählung von Spalten, die die Tabelle definieren.

http://www.sqlite.org/autoinc.html

Es ist auch einfacher, dies als die ROWID anstelle der AUTOINCREMENT-Option zu verwenden, die bewirken kann, dass _ID von der ROWID abweichen kann. Durch das Binden von _ID an ROWID bedeutet dies, dass der Primärschlüssel von insert / insertOrThrow zurückgegeben wird; Wenn Sie einen ContentProvider schreiben, können Sie diesen Schlüssel im zurückgegebenen Uri verwenden.

Eine andere Möglichkeit, mit dem Fehlen einer _id-Spalte in der Tabelle umzugehen, besteht darin, eine Unterklasse von CursorWrapper zu schreiben, die bei Bedarf eine _id-Spalte hinzufügt.

Dies hat den Vorteil, dass keine Änderungen an Tabellen oder Abfragen erforderlich sind.

Ich habe eine solche class geschrieben, und wenn es von Interesse ist, kann es unter https://github.com/cmgharris/WithIdCursorWrapper gefunden werden