微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

android.database.sqlite.SQLiteException:没有这样的表:国家代码 1 SQLITE_ERROR

如何解决android.database.sqlite.SQLiteException:没有这样的表:国家代码 1 SQLITE_ERROR

我刚刚在我的项目中实现了 sqlite 数据库,该应用程序在旧应用程序中运行良好,但是在我将数据库文件传输到另一个应用程序并尝试运行它之后,它给了我这个错误

android.database.sqlite.sqliteException: no such table: countries (code 1 sqlITE_ERROR):,while compiling: SELECT * FROM countries

现在我尝试运行运行良好的旧应用程序,现在它也无法运行并出现相同的错误

我对此进行了大量搜索并尝试以这些方式解决错误,但对我没有任何作用

  • 正在清除数据、重新安装应用...
  • 正在更改数据库的版本和名称...
  • 在 onopen 中调用 onCreate...

和其他一些类似的,但没有任何技巧

这是我的整个数据库助手类(修改后)

class LocationDB(private val myContext: Context) {
    private var dbPath: String? = null
    private var db: sqliteDatabase? = null
    private var dbHelper: DatabaseHelper

    inner class DatabaseHelper
        (context: Context?) : sqliteOpenHelper(context,DB_NAME,null,5) {
        override fun onCreate(db: sqliteDatabase) {}

        override fun onUpgrade(db: sqliteDatabase,oldVersion: Int,newVersion: Int) {
            if(newVersion>oldVersion)
                copyDataBase()
        }

        override fun onopen(db: sqliteDatabase?) {
            if (db != null) {
                onCreate(db)
            }
        }
    }

    @Throws(IOException::class)
    fun createDataBase() {
        val dbExist = checkDataBase()
        if (!dbExist) {
            dbHelper.readableDatabase
            try {
                copyDataBase()
            } catch (e: IOException) {
                throw Error("Error copying database")
            }
        }
    }

    private fun checkDataBase(): Boolean {
        var checkDB: sqliteDatabase? = null
        try {
            val myPath = dbPath + DB_NAME
            checkDB = sqliteDatabase.openDatabase(
                myPath,sqliteDatabase.OPEN_READONLY
            )
        } catch (e: sqliteException) {
        }
        checkDB?.close()
        return checkDB != null
    }

    @Throws(IOException::class)
    private fun copyDataBase() {
        val myInput = myContext.assets.open(DB_NAME)

        val outFileName = dbPath + DB_NAME

        val myOutput: OutputStream = FileOutputStream(outFileName)

        val buffer = ByteArray(1024)
        var length: Int
        while (myInput.read(buffer).also { length = it } > 0) {
            myOutput.write(buffer,length)
        }

        myOutput.flush()
        myOutput.close()
        myInput.close()
    }

    @Throws(sqlException::class)
    fun openDB(): LocationDB {
        db = dbHelper.writableDatabase
        return this
    }

    fun closeDB() {
        dbHelper.close()
    }

    val countries: Cursor?
        get() {
            val query = "SELECT * FROM countries"
            return db?.rawQuery(query,null)
        }

    fun getStateAsPerCountry(country_id: String): Cursor? {
        val query = "SELECT * FROM states where country_id=$country_id"
        return db?.rawQuery(query,null)
    }

    fun getCitiesAsPerState(state_id: String): Cursor? {
        val query = "SELECT * FROM cities where state_id=$state_id"
        return db?.rawQuery(query,null)
    }

    companion object {
        const val DB_NAME = "Location.db"
    }

    init {
        dbPath = myContext.filesDir.path + myContext.packageName + "/databases/"
        dbHelper = DatabaseHelper(myContext)
    }
}

已编辑 (10/06/2021)

我看到设备文件资源管理器,我知道数据库的路径认是/data/data/com.my.package/databases/Location.db。当我在错误断点处调试应用程序时,我发现路径不同,或者我们可以说数据库助手正在从不同的路径 /data/user/0/com.my.package/databases/Location 获取数据库。 db 不存在,所以很明显,如果没有确切的路径,表将始终为空或不创建。但问题是我们为什么以及如何初始化正确的路径。

为此,我这样做并获得了确切的路径,但它仍然无法正常工作

val countries: Cursor?
        get() {
            db = sqliteDatabase.openDatabase(dbPath,sqliteDatabase.OPEN_READONLY) 
            val query = "SELECT * FROM countries"
            return db?.rawQuery(query,null)
        } 

这是数据库图片

enter image description here

解决方法

据我了解您的问题,我认为您共享的数据助手类没有任何问题。看起来很完美。我可以看到 Location.db 中有国家/地区表,正如您所说,数据库放置在正确的路径中,但数据库没有该表,这意味着它应该是空的。

所以问题出在你使用数据库的那个类上,因为正在创建虚拟数据库,但它没有从你现成的 Location.db 中获取数据,这意味着它没有创建那个电话

db.createDataBase()

在该类的 onCreate 中调用其他函数(如国家/地区)之前。

,

检查您的数据库检查器以了解表 'countries' 是否真的存在。

如果不是,您需要在您的数据库助手中重新创建它。

,

确保表名 countries 与查询中的拼写相同。

Update

尝试将您的路径硬编码为

dbPath = "/data/data/com.my.package/databases/"+DB_NAME 
,

"当我调试查询时,变量 db 返回 "/data/user/0/com.my.package/databases/Location.db" 而 dbPath 是 "/data/data/com.my.package/databases /”这意味着您的查询检查数据库位于“用户”文件夹下而不是数据文件夹下。 这就是为什么你得到 android.database.sqlite.SQLiteException: no such table: countries .

要检查国家/地区表是否在您的应用中,请打开查看->工具窗口->设备文件资源管理器

enter image description here

在数据文件夹下找到“/data/data/com.my.package/databases/Location.db”

使用SQLLiteDatabaseBrowserPortable检查Location db下的表。如果Location.db不在数据库下,您可以使用SQLLiteDatabaseBrowserPortable手动创建新的db和表。

然后,将数据库路径更改为“/data/data/com.my.package/databases/Location.db”

然后运行你的程序。希望会成功。

,

通常数据库存储在 context.getDatabasePath(name) 下。此功能的优点是系统确保选择正确的路径而不是硬编码。

当您的设备连接到 Android Studio 时,您可以检查您的 Device File Explorer 设备上存储了哪些文件,甚至可以访问您的应用的沙箱,在其中可以找到数据库。您可以在那里下载沙箱中的文件并在您的计算机上本地打开它。

如果数据库配置正确,您甚至可以使用 Database Inspector

在调试代码时,您可能会发现数据库复制错误的位置导致数据库没有您正在查询的表。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。