SQLiteException code 0 android data_error ai_generated true

android.database.sqlite.SQLiteException: Cannot read from cursor: column 'price' has type REAL but expected INTEGER (code 0)

ID: android/sqlite-cursor-column-type-mismatch

Also available as: JSON · Markdown · 中文
92%Fix Rate
88%Confidence
1Evidence
2023-11-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
Android 11 (API 30) active
Android 12 (API 31) active
Android 13 (API 33) active

Root Cause

Cursor attempts to read a REAL column as INTEGER via getInt(), causing type mismatch in SQLite's dynamic typing system.

generic

中文

游标尝试通过 getInt() 将 REAL 列读取为 INTEGER,导致 SQLite 动态类型系统中的类型不匹配。

Official Documentation

https://developer.android.com/reference/android/database/sqlite/SQLiteException

Workarounds

  1. 95% success Use `cursor.getDouble(cursor.getColumnIndexOrThrow("price"))` instead of getInt() to read REAL columns correctly.
    Use `cursor.getDouble(cursor.getColumnIndexOrThrow("price"))` instead of getInt() to read REAL columns correctly.
  2. 92% success In Room, annotate the field as `Double` (not Int) in the entity class: `@ColumnInfo(name = "price") val price: Double`
    In Room, annotate the field as `Double` (not Int) in the entity class: `@ColumnInfo(name = "price") val price: Double`
  3. 85% success Use `cursor.getType(columnIndex)` to check the type before reading: if type == Cursor.FIELD_TYPE_FLOAT, use getDouble(); else getInt().
    Use `cursor.getType(columnIndex)` to check the type before reading: if type == Cursor.FIELD_TYPE_FLOAT, use getDouble(); else getInt().

中文步骤

  1. Use `cursor.getDouble(cursor.getColumnIndexOrThrow("price"))` instead of getInt() to read REAL columns correctly.
  2. In Room, annotate the field as `Double` (not Int) in the entity class: `@ColumnInfo(name = "price") val price: Double`
  3. Use `cursor.getType(columnIndex)` to check the type before reading: if type == Cursor.FIELD_TYPE_FLOAT, use getDouble(); else getInt().

Dead Ends

Common approaches that don't work:

  1. Cast the column value to int in SQL query: `CAST(price AS INTEGER)` 70% fail

    This truncates decimals, losing precision; the real fix is to read as getDouble().

  2. Change column type in CREATE TABLE to INTEGER 85% fail

    SQLite is dynamically typed; the column type only affects affinity, not actual stored values. Existing data remains REAL.

  3. Use getString() and parse to int 90% fail

    Parsing '12.99' to int throws NumberFormatException or truncates incorrectly.