Intereting Posts
Как настроить Android ActionBar для отображения пользовательского представления перед вкладками? Android SQLite Exception: невозможно закрыть из-за нефинализированных операторов Удаление дополнительных функций из переданного Intent Есть ли какой-либо прослушиватель в Android SearchView для уведомления, если SearchView будет расширен и готов принять вход? Быстрая выгрузка растровых изображений из памяти Как принудительно обновлять информацию о конфигурации? Связывание и отключение Android-сервиса в / из фрагмента (в ViewPager) Повторное использование сеансов SSL в Android с HttpClient Жизненный цикл замененного ViewPager и BackStack? Извлечение только изображений из галереи при устревании намерений выбора изображения для Android. Защита от свободы Поставщик плавного местоположения, похоже, не использует приемник GPS Как установить adSize? Сервер Adb не отвечает Сравнение производительности: AsyncTasks vs Threads

Android-колонка «_id» не существует?

У меня проблемы с чем-то, что работает в примере с Блокнотом. Вот код из 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); 

Этот код работает нормально. Но, чтобы быть ясным, я запустил утилиту ADB и запустил SQLite 3. Я проверил схему следующим образом:

Sqlite> .schema

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

Мне все кажется хорошим.


Теперь о моем приложении, которое, насколько я вижу, в основном то же самое с несколькими незначительными изменениями. Я упростил и упростил свой код, но проблема не устранена.

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

Когда я запускаю свое приложение, я получаю исключение RuntimeException и следующие отпечатки в LogCat из своего Log.e() :

Сообщение LogCat:

Java.lang.IllegalArgumentException: column '_id' не существует

Итак, вернемся к SQLite 3, чтобы узнать, что отличается от моей схемы:

Sqlite> .schema CREATE TABLE android_metadata (locale TEXT); Круги CREATE TABLE (автоинкремент целочисленного первичного ключа целых чисел, целочисленное целое число, действительный радиус, x real, y real);

Я не вижу, как мне не хватает «_id».

Что я сделал не так?

Одна вещь, которая отличается от моего приложения и примера с Notepad, заключается в том, что я начал с создания моего приложения с нуля с помощью мастера Eclipse, в то время как пример приложения уже собран. Есть ли какие-то экологические изменения, которые мне нужно сделать для нового приложения для использования базы данных SQLite?

Solutions Collecting From Web of "Android-колонка «_id» не существует?"

Я вижу, документация для CursorAdapter гласит:

Курсор должен содержать столбец с именем _id или этот класс не будет работать.

SimpleCursorAdapter является производным классом, поэтому представляется, что это утверждение применяется. Однако заявление технически неверно и несколько вводит в заблуждение новичку. Набор результатов для курсора должен содержать _id , а не сам курсор.
Я уверен, что это понятно для администратора баз данных, потому что эта краткая документация им понятна, но для тех новичков, которые неполны в заявлении, вызывает путаницу. Курсоры похожи на итераторы или указатели, они не содержат ничего, кроме механизма трансверсации данных, они не содержат самих столбцов.

Документация Loaders содержит пример, где можно увидеть, что _id включен в параметр проекции .

 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<Cursor> onCreateLoader(int id, Bundle args) { // ... return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, select, null, Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"); } 

На это был дан ответ, и я хотел бы сделать его более всеобъемлющим.

SimpleCursorAdapter требует, чтобы результирующий набор Cursor должен содержать столбец с именем «_id». Не спешите изменять схему, если вы не указали столбец «_id» в своей таблице. SQLite автоматически добавляет скрытый столбец с именем «rowid» для каждой таблицы. Все, что вам нужно сделать, это просто выбрать rowid явно и псевдоним как «_id» Ex.

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

Код Тима Ву действительно работает …

Если вы используете db.query, то это будет так …

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

То, что решило мою проблему с этой ошибкой, состояло в том, что я не включил столбец _id в мой запрос БД. Добавив это, я решил проблему.

Вероятно, это уже не актуально, но сегодня я столкнулся с одной и той же проблемой. Оказывается, имена столбцов чувствительны к регистру. У меня был столбец _ID, но Android ожидает столбец _id.

Да, я также изменяю строковый запрос SELECT, чтобы исправить эту проблему.

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

Если вы прочитали документы на sqlite, создание любого столбца типа INTEGER PRIMARY KEY будет внутренне псевдонимом ROWID, поэтому не стоит добавлять псевдоним в каждый SELECT, отклоняясь от любых общих утилит, которые могут использовать что-то вроде Перечисление столбцов, определяющих таблицу.

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

Также более просто использовать это как ROWID вместо опции AUTOINCREMENT, которая может привести к тому, что _ID может отклоняться от ROWID. При привязке _ID к ROWID это означает, что первичный ключ возвращается из insert / insertOrThrow; Если вы пишете ContentProvider, вы можете использовать этот ключ в возвращаемом Uri.

Другой способ справиться с отсутствием столбца _id в таблице – написать подкласс CursorWrapper, который при необходимости добавит столбец _id.

Это имеет то преимущество, что не требуется никаких изменений в таблицах или запросах.

Я написал такой класс, и если это интересно, его можно найти на странице https://github.com/cmgharris/WithIdCursorWrapper