Android SQLite Value must be ≥ 0 getColumnIndex Kotlin
Asked Answered
F

1

5

I am getting an error in Android Studio to do with my Cursor.

I have the following line in my code

val dataText = cursor.getString(cursor.getColumnIndex(MyDbNameClass.COLUMN_NAME_TITLE))

I tried using cursor.getColumnIndexOrThrow() but it didn't help I am new to android, hope you can help me. Here is my code.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvTest"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/edTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.437"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.071" />

    <EditText
        android:id="@+id/edDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.437"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.166" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="onClickSave"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.796" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

package com.example.todo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.TextView
import com.example.todo.db.MyDbManager

class MainActivity : AppCompatActivity() {

    val myDbManager = MyDbManager(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    fun onClickSave(view: View) {
        val edTitle = findViewById<EditText>(R.id.edTitle)
        val edDesc = findViewById<EditText>(R.id.edDesc)
        val tvTest = findViewById<TextView>(R.id.tvTest)
        tvTest.text = ""
        myDbManager.openDb()
        myDbManager.insertToDb(edTitle.text.toString(), edDesc.text.toString())
        val dataList = myDbManager.readDbData()
        for (item in dataList) {
            tvTest.append(item)
            tvTest.append("\n")
        }
    }
    override fun onDestroy() { //при выходе с активити
        super.onDestroy()
        myDbManager.closeDb()
    }
}

MyDbNameClass.kt

package com.example.todo.db

import android.provider.BaseColumns

object MyDbNameClass: BaseColumns {
    const val TABLE_NAME = "info"
    const val COLUMN_NAME_TITLE = "title"
    const val COLUMN_NAME_DESC = "desc"

    const val DATABASE_VERSION = 1
    const val DATABASE_NAME = "ToDoDb.db"

    const val CREATE_TABLE = "CREATE TABLE $TABLE_NAME (" +
            "${BaseColumns._ID} INTEGER PRIMARY KEY, $COLUMN_NAME_TITLE TEXT, $COLUMN_NAME_DESC TEXT)"
    const val SQL_DELETE_TABLE = "DROP TABLE IF EXISTS $TABLE_NAME"
}

MyDbHelper.kt

package com.example.todo.db

import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.provider.BaseColumns

class MyDbHelper(context: Context) : SQLiteOpenHelper(context, MyDbNameClass.DATABASE_NAME, null, MyDbNameClass.DATABASE_VERSION) {
    override fun onCreate(db: SQLiteDatabase?) {
        db?.execSQL(MyDbNameClass.CREATE_TABLE)
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
        db?.execSQL(MyDbNameClass.SQL_DELETE_TABLE)
        onCreate(db)
    }
}

MyDbManager.kt (error here)

package com.example.todo.db

import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase

class MyDbManager(context: Context) {
    private val myDbHelper = MyDbHelper(context)
    private var db: SQLiteDatabase? = null

    fun openDb(){
        db = myDbHelper.writableDatabase
    }
    fun insertToDb(title: String, desc: String){
        val values = ContentValues().apply {
            put(MyDbNameClass.COLUMN_NAME_TITLE, title)
            put(MyDbNameClass.COLUMN_NAME_DESC, desc)
        }
        db?.insert(MyDbNameClass.TABLE_NAME, null, values)
    }

    fun readDbData() : ArrayList<String> {
        val dataList = ArrayList<String>()
        val cursor = db?.query(MyDbNameClass.TABLE_NAME, null, null,
            null, null, null, null)
        db?.rawQuery(MyDbNameClass.TABLE_NAME, null)
        var k = 1
        while (cursor?.moveToNext()!!){
            val dataText = cursor.getString(cursor.getColumnIndex(MyDbNameClass.COLUMN_NAME_TITLE))
            dataList.add(dataText.toString())
        }
        cursor.close()
        return dataList
    }
    fun closeDb(){
        myDbHelper.close()
    }
}
Foreground answered 3/3, 2022 at 13:29 Comment(6)
Can you please add the error (exception?) log?Xenogamy
looks like MyDbNameClass.COLUMN_NAME_TITLE doesn't exist in your database, as getColumnIndex returned probably -1, as when it can't find desired column. check out DebugDB tool, inspect your database. btw. there should be CREATE TABLE IF NOT EXISTS for avoiding table creation try with every app enterAmalita
Hi @Xenogamy I answered you belowForeground
Hi @Amalita How can I check out DebugDB tool? I'm new to this and don't know how to do it.Foreground
Please add the image to the question and not as an Answer to your question. (Edit your question, add the image and save)Xenogamy
@Xenogamy Here are my errors. In the Project Errors tab, an error about a value greater than or equal to 0. When I add IF NOT EXISTS - nothing changes, just exits the app, no error (i.sstatic.net/LxAqf.png)Foreground
F
6

This is a warning

Value must be ≥ 0 but getColumnIndex can be -1

Jorgesys Android "Value must be ≥ 0 but getColumnIndex can be -1"

that indicates that in this method, the value of getColumnIndex(..) must be ≥ 0 , but it would be -1

getColumnIndex() Returns the zero-based index for the given column name, or -1 if the column doesn't exist. If you expect the column to exist use getColumnIndexOrThrow(String) instead, which will make the error more clear.


You have two options:

Use getColumnIndexOrThrow() instead of getColumnIndex()

getColumnIndexOrThrow() Returns the zero-based index for the given column name, or throws IllegalArgumentException if the column doesn't exist.

Disabling the warning using the the annotation:

    @SuppressLint("Range")

To disable this warning add the annotation @SuppressLint("Range") because the method getColumnIndex() requires a value in a particular numerical range ( ≥ 0) .

@SuppressLint("Range")
fun readDbData() : ArrayList<String> {
        val dataList = ArrayList<String>()
        val cursor = db?.query(MyDbNameClass.TABLE_NAME, null, null,
            null, null, null, null)
        db?.rawQuery(MyDbNameClass.TABLE_NAME, null)
        var k = 1
        while (cursor?.moveToNext()!!){
            val dataText = cursor.getString(cursor.getColumnIndex(MyDbNameClass.COLUMN_NAME_TITLE))
            dataList.add(dataText.toString())
        }
        cursor.close()
        return dataList
    }
Fissionable answered 1/11, 2023 at 22:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.