首页 > 解决方案 > 无如表:名称 kotlin SQLite

问题描述

我收到一个关于 no such talbe 的错误:我从数据库调用数据时的帐户。

我的数据库名称是“account.db”,表名称是“Account”。有两列,第一列是“姓名”,第二列是“电子邮件”。

我正在用科特林语言写作。请在下面查看我的 DBHelper 和 DBManager。

import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.os.Build
import android.widget.Toast
import java.io.FileOutputStream
import java.io.IOException
import java.lang.Exception
import java.util.ArrayList

class  DbManager {

    var DB_PATH = ""
    var DB_NAME = "account.db"
    val dbVersion = 1
    //CREATE TABLE IF NOT EXISTS MyNotes (ID INTEGER PRIMARY KEY,title TEXT, Description TEXT);"
//    val sqlCreateTable = "CREATE TABLE IF NOT EXISTS " + dbTable + " (" + colID + " INTEGER PRIMARY KEY," +
//            colTitle + " TEXT, " + colDes + " TEXT);"
    var sqlDB: SQLiteDatabase? = null

    constructor(context: Context) {
        var db = DBHelper(context)
        sqlDB = db.writableDatabase
    }

    inner class DBHelper(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, dbVersion) {
        var mDatabase: SQLiteDatabase? = null
        var mContext: Context? = null

        //Todo: Get All Data users
        fun getAllUsers(): List<Account>?{
            val temp = ArrayList<Account>()
            val db = writableDatabase
            var c: Cursor?

            try {
                c = db.rawQuery("SELECT * FROM Account ", null)
                if (c == null) return null
                c.moveToFirst()

                do {
                    val account = Account(c.getString(c.getColumnIndex("name")), c.getString(c.getColumnIndex("email")))
                    temp.add(account)
                } while (c.moveToNext())
                c.close()
            } catch (e: Exception) {
            }

            db.close()
            return temp
        }

        fun createDataBase() {
            //Todo: Create Database
            val isDBExist = checkDataBase()
            if (isDBExist) { } else {
                this.readableDatabase
                try {
                    copyDataBase()
                    Toast.makeText(this.mContext, "Copy has been finished.", Toast.LENGTH_SHORT).show()
                } catch (ex: Exception) {
                }
            }
        }

        init {

            if (Build.VERSION.SDK_INT > 17) {
                DB_PATH = context.applicationInfo.dataDir + "/databases/"
            } else {
                DB_PATH = "/data/data/" + context.packageName + "/databases/"
            }

            this.mContext = mContext
        }

        override fun close() {
            if (mDatabase != null)
                mDatabase!!.close()
            super.close()
        }

        fun checkDataBase(): Boolean {
            //Todo: Check Database
            var tempDB: SQLiteDatabase? = null
            try {
                val path = DB_PATH + DB_NAME
                tempDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY)
            } catch (ex: Exception) {
            }

            if (tempDB != null)
                tempDB.close()
            return if (tempDB != null) true else false
        }

        fun copyDataBase() {
            //Todo:Copy Database

            try {
                val myInput = mContext!!.assets.open(DB_NAME)
                val outputFileName = DB_PATH + DB_NAME
                val myOutput = FileOutputStream(outputFileName)

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

            } catch (e: IOException) {
                e.printStackTrace()
            }

        }

        fun openDataBase() {
            //Todo: Open Database
            val path = DB_PATH + DB_NAME
            mDatabase = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READWRITE)
        }

        override fun onCreate(db: SQLiteDatabase) {
            createDataBase()
        }

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

//        companion object {
//            var DB_PATH = ""
//            var DB_NAME = "account.db"
//        }
    }

}

这是我的 MainActivity.kt

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.row.*
import kotlinx.android.synthetic.main.row.view.*
import java.util.ArrayList

class MainActivity : AppCompatActivity() {
    var lstUsers=ArrayList<Account>()
     lateinit var dbHelper: DBHelper

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         dbHelper = DBHelper(applicationContext)
         dbHelper.createDataBase()
    }

    fun buGetData(v: View){
        //Todo: Load Data from db set to listview
        LoadData()
    }


    fun LoadData(){

        val accout = dbHelper.getAllUsers()
        //this.listView.removeAllViews()
        //List View
        for (list in accout!!) {
            lstUsers.add(list)
        }


        var myNotesAdapter= MyAdapter(this, lstUsers)
        listView.adapter=myNotesAdapter

    }


    inner class MyAdapter:BaseAdapter {

        var listMyAdapter = ArrayList<Account>()
        var context:Context?=null
        constructor(context:Context, listMyAdapter:ArrayList<Account>):super(){
            this.listMyAdapter=listMyAdapter
            this.context=context
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            var myView=layoutInflater.inflate(R.layout.row,null)
            var myAc=listMyAdapter[position]
            myView.txtUser.text = myAc.userName
            myView.txtEmail.text = myAc.email

            return myView
        }

        override fun getItem(position: Int): Any {
         return listMyAdapter[position]
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getCount(): Int {
            return listMyAdapter.size
        }

    }
}

错误如下图所示。

在此处输入图像描述

请帮我解决它。最好的问候, Sai Tawng Pha

标签: sqlitekotlin

解决方案


我已经通过更新几行代码解决了我的问题。我想分享给其他人。

如果有人想用 Kotlin 从 Assests 文件夹中读取现有的数据库文件。请看下面。

MainActivity.kt

import android.content.Context
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.row.*
import kotlinx.android.synthetic.main.row.view.*
import java.util.ArrayList

class MainActivity : AppCompatActivity() {
    var lstUsers=ArrayList<Account>()
    var dbHelper: DBHelper? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        dbHelper = DBHelper(this)
        dbHelper!!.createDatabase()
    }

    fun buGetData(v: View){
        lstUsers = this.dbHelper!!.getAllUsers() as ArrayList<Account>
        this.container.removeAllViews()
        //List View
        for (account in lstUsers) {
            // val inflater = baseContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            // val addView = inflater.inflate(R.layout.row, null)
            var addView = layoutInflater.inflate(R.layout.row,null)
            addView.txtUser.text = account.userName
            addView.txtEmail.text = account.email
            //add View
            container.addView(addView)
        }
    }
}

DBHelper.kt

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.util.Log;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

public class DbHelper extends SQLiteOpenHelper {

    private static String DB_PATH= "";
    private static String DB_NAME= "account.db";
    private SQLiteDatabase mDatabase;
    private final Context mContext;

    public DbHelper(Context context) {
        super(context, DB_NAME, null, 11);
        this.mContext = context;
        if(Build.VERSION.SDK_INT >= 17){
            this.DB_PATH = context.getApplicationInfo().dataDir+"/databases/";
            Log.e("Path:", DB_PATH);
        }else {
            this.DB_PATH = "/data/data/"+context.getPackageName()+"/databases/";
            Log.e("Path:", DB_PATH);
        }

    }

    @Override
    public synchronized void close() {
        if(mDatabase != null){
            mDatabase.close();
        }
        super.close();
    }

    private boolean checkDatabase(){
        //Todo: Check Database
        SQLiteDatabase tempDB = null;
        try {
            String path = DB_PATH+DB_NAME;
            tempDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        }catch (Exception ex){}
        if(tempDB!=null){
            tempDB.close();
        }
        return tempDB!=null?true:false;
    }

    public void copyDatabase(){
        //Todo: Copy Database
        try {
            InputStream myInput = mContext.getAssets().open(DB_NAME);
            String outputFileName = DB_PATH+DB_NAME;
            OutputStream myOutput = new FileOutputStream(outputFileName);

            byte[] buffer = new byte[1024];
            int length;
            while ((length=myInput.read(buffer))>0){
                myOutput.write(buffer,0,length);
            }
            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void openDatabase(){
        //Todo: Open Database
        String path = DB_PATH+DB_NAME;
        mDatabase = SQLiteDatabase.openDatabase(path,null, SQLiteDatabase.OPEN_READWRITE);
    }

    public void createDatabase(){
        //Todo: Create Database
        boolean isDBExist = checkDatabase();
        if (isDBExist){
        }else {
            this.getReadableDatabase();
            try {
                copyDatabase();
            }catch (Exception e){throw new Error("Copy Database Error");}
        }
    }

    public List<Account>getAllUsers(){
        //Todo: Get All Users
        List<Account> temp = new ArrayList<Account>();
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor c;
        try {
            c = db.rawQuery("SELECT * FROM Account", null);
            if (c==null) return null;
            c.moveToFirst();
            do {
                Account account = new Account(c.getString(c.getColumnIndex("name")),(c.getString(c.getColumnIndex("email"))));
                temp.add(account);
            }while (c.moveToNext());
            c.close();
        }catch (Exception e){}
        db.close();
        return temp;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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">


    <Button
        android:id="@+id/buGetData"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="Get Data" />

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/buGetData"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="-15dp"
        android:orientation="vertical"></LinearLayout>
</RelativeLayout>

行.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/txtUserName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="TextView"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/txtEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="TextView" />
</LinearLayout>

请看下面的截图。

在此处输入图像描述

注意:请从 Assets 文件夹中替换您的数据库文件,并在 createDataBase 函数中从 DBHelper.kt 中更改您的数据库名称和表名称。

我希望,它对你有用。


推荐阅读