Error in my first table in kotlin

2019-09-23 15:05发布

问题:

I'm facing a problem when I try to insert a column in the database using Kotlin in Android.

This is the error:

08-04 19:45:03.781 14302-14302/com.example.hello.note E/Zygote: v2 08-04 19:45:03.781 14302-14302/com.example.hello.note E/Zygote: accessInfo : 0 08-04 19:45:20.471 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:45:20.521 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:45:20.531 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:45:20.541 14302-14302/com.example.hello.note E/MotionRecognitionManager: mSContextService = null 08-04 19:45:20.541 14302-14302/com.example.hello.note E/MotionRecognitionManager: motionService = com.samsung.android.motion.IMotionRecognitionService$Stub$Proxy@78b77 08-04 19:45:47.991 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:45:47.991 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:45:47.991 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:47:40.311 14302-14302/com.example.hello.note E/Qmage: isQIO : stream is not a QIO file 08-04 19:48:14.131 14302-14302/com.example.hello.note E/SQLiteLog: (1) no such table: Notes 08-04 19:48:14.141 14302-14302/com.example.hello.note E/SQLiteDatabase: Error inserting Title=note Desc=desc android.database.sqlite.SQLiteException: no such table: Notes (code 1): , while compiling: INSERT INTO Notes(Title,Desc) VALUES (?,?) ################################################################# Error Code : 1 (SQLITE_ERROR) Caused By : SQL(query) error or missing database. (no such table: Notes (code 1): , while compiling: INSERT INTO Notes(Title,Desc) VALUES (?,?)) ################################################################# at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method) at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1004) at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:569) at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) at android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:59) at android.database.sqlite.SQLiteStatement.(SQLiteStatement.java:31) at android.database.sqlite.SQLiteDatabase.insertWithOnConflict(SQLiteDatabase.java:1633) at android.database.sqlite.SQLiteDatabase.insert(SQLiteDatabase.java:1505) at com.example.hello.note.DbManger.Insert(DbManger.kt:40) at com.example.hello.note.addNotes.buAdd(addNotes.kt:24) at java.lang.reflect.Method.invoke(Native Method) at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) at android.view.View.performClick(View.java:5721) at android.widget.TextView.performClick(TextView.java:10931) at android.view.View$PerformClick.run(View.java:22620) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:7409) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Database code:

class DbManger(context: Context) {
    val dbName = "MyNotes"
    val dbTable = "Notes"
    val colID = "ID"
    val colTitle = "Title"
    val colDesc = "Desc"
    var dbVer = 4

    val sqlCreateTable = "CREATE TABLE IF NOT EXISTS " + dbTable + "(" + colID + " INTEGER PRIMARY KEY," + colTitle + " TEXT," + colDesc + " TEXT " + ");"
    var sqlDataBase: SQLiteDatabase? = null

    inner class dbHelperNotes : SQLiteOpenHelper {
        var context: Context? = null

        constructor(context: Context) : super(context, dbName, null, dbVer) {
            this.context = context

        }

        override fun onCreate(p0: SQLiteDatabase?) {
            p0!!.execSQL(sqlCreateTable)
            Toast.makeText(this.context, "Database is created", Toast.LENGTH_LONG).show()
        }

        override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
            p0!!.execSQL("drop table IF EXISTS " + dbTable)
        }


    }

    fun Insert(values: ContentValues): Long {
        val ID = sqlDataBase!!.insert(dbTable, "", values)
        return ID
    }

    init {
        var db = dbHelperNotes(context)
        sqlDataBase = db.writableDatabase
    }
}

回答1:

@laalto is right, you need to re-create your table once you've dropped it, you need to add a call to onCreate(p0) inside your onUpgrade() method.


I removed a couple of unneeded fields on your class, this is how it looks now:

class DbManger(context: Context) {
    val dbName = "MyNotes"
    val dbTable = "Notes"
    val colID = "ID"
    val colTitle = "Title"
    val colDesc = "Desc"
    var dbVer = 4

    val sqlCreateTable = "CREATE TABLE IF NOT EXISTS $dbTable($colID INTEGER PRIMARY KEY,$colTitle TEXT,$colDesc TEXT);"
    var sqlDataBase: SQLiteDatabase? = null

    inner class dbHelperNotes(val context: Context) : SQLiteOpenHelper(context, dbName, null, dbVer) {
        override fun onCreate(database: SQLiteDatabase?) {
            database?.execSQL(sqlCreateTable)
            Toast.makeText(context, "Database is created", Toast.LENGTH_LONG).show()
        }

        override fun onUpgrade(database: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
            database?.execSQL("drop table IF EXISTS " + dbTable)
            onCreate(database)
        }
    }

    fun insert(values: ContentValues): Long {
        val id = sqlDataBase!!.insert(dbTable, "", values)
        return id
    }

    init {
        val db = dbHelperNotes(context)
        sqlDataBase = db.writableDatabase
    }
}

I believe you also have a typo on your class name, should be 'DbManager'.



回答2:

Your database version is already at 4 but your onUpgrade merely drops the table but does not create the required tables.

If you want data-losing upgrades, you can just invoke onCreate in onUpgrade after dropping old tables. Or at development time, it's often just easier to uninstall and reinstall your app. See When is SQLiteOpenHelper onCreate() / onUpgrade() run? for more about how SQLiteOpenHelper works.