Android SQLite:尝试从数据库中获取数据时没有此类表错误

时间:2019-05-27 06:34:18

标签: android android-sqlite sqliteopenhelper

我正在尝试使用通过数据库浏览器从csv文件创建的数据库。 我尝试卸载并重新安装该应用程序。还升级了数据库版本,仍然发生相同的错误! 检查了我的数据库路径,以及是否正在创建文件。

DatabaseHelper.java

package com.timespro.bookaseat.Model;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import com.timespro.bookaseat.Students;

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


public class DatabaseHelper extends SQLiteOpenHelper {

    private static final String TABLE_NAME1 = "StudentDetails";


    private static final int DB_VERSION = 5;
    private static String DB_NAME = "data.sqlite";
    private  String DB_PATH;
    private  Context mContext;
    private SQLiteDatabase mDataBase;
    private boolean mNeedUpdate = false;


    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        this.mContext = context;
        DB_PATH = context.getDatabasePath(DB_NAME).getAbsolutePath();
        Log.d("DB_Path",DB_PATH);
    }

    public void updateDataBase() throws IOException {
        if (mNeedUpdate) {
            File dbFile = new File(DB_PATH + DB_NAME);
            if (dbFile.exists())
                dbFile.delete();


            copyDataBase();

            mNeedUpdate = false;
        }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

        }catch(SQLiteException e){

            Log.d("DB","DB doesn't exist!");

        }

        if(checkDB != null){

            checkDB.close();

        }

        return checkDB != null;
    }


    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transferring bytestream.
     * */
    private void copyDataBase() throws IOException{
        Log.d("DB","Database copied!");
        //Open your local db as the input stream
        InputStream myInput = mContext.getAssets().open(DB_NAME);

        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;

        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);

        //transfer bytes from the input file to the output file
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0){
            myOutput.write(buffer, 0, length);
        }

        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();

    }
    /**
     * Creates a empty database on the system and rewrites it with your own database.
     **/
    public void createDataBase() throws IOException{

        boolean dbExist = checkDataBase();

        if(dbExist){
            Log.d("DatabaseHelper","DB already exists!");
            //do nothing - database already exist
        }else{

            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.
            this.getReadableDatabase();

            try {

                copyDataBase();

            } catch (IOException e) {

                throw new Error("Error copying database");

            }
        }

    }

    private void copyDBFile() throws IOException {
        Log.d("DB","DB File created on phone");
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        //InputStream mInput = mContext.getResources().openRawResource(getResources().getIdentifier("data","raw", getPackageName()));
        OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0)
            mOutput.write(mBuffer, 0, mLength);
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public void openDataBase() throws SQLException{

        //Open the database
        String myPath = DB_PATH + DB_NAME;
        mDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
        Log.d("DB","DB opened");
    }

    @Override
    public void onConfigure(SQLiteDatabase db) {
        super.onConfigure(db);
        db.setForeignKeyConstraintsEnabled(true);
    }
    @Override
    public synchronized void close() {

        if(mDataBase != null)
            mDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.d("DB","DB created");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            mNeedUpdate = true;
    }
    public ArrayList<Students> getAllData(){
        ArrayList<Students> students = new ArrayList<>();
        SQLiteDatabase db = this.getWritableDatabase();
        try {
            Cursor res = db.rawQuery("select * from "+TABLE_NAME1, null);
            res.moveToFirst();
            while(res.moveToNext()) {
                int uid = Integer.parseInt(res.getString(0));   //0 is the number of id column in your database table
                String name = res.getString(1);
                String pass = res.getString(2);
                String city = res.getString(3);
                String centre = res.getString(4);
                String inst = res.getString(5);
                String pro = res.getString(6);
                String batch = res.getString(7);
                String days = res.getString(8);
                String time = res.getString(9);

                Students newStudents = new Students(uid,name,pass,city,centre,inst,pro,batch,days,time);
                students.add(newStudents);
            }
            res.close();
        }
        catch(SQLiteException sql){
            Log.d("DatabaseError!","No table found!");
        }
        finally {

            db.close();
        }

        return students;
    }

}

错误消息: E / SQLiteLog:(1)没有这样的表:StudentDetails D / DatabaseError !:找不到表!

3 个答案:

答案 0 :(得分:0)

如果您拥有No such table error,则可以执行以下操作:

A。尝试增加数据库架构。

B。从设备上卸载应用程序,然后重新安装。

C。重命名表格,SQLite

的背景可能存在一些问题

答案 1 :(得分:0)

问题很可能是该设备是Android Pie或更高版本,在这种情况下,默认日志记录已从日志更改为WAL。

结合使用
//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();

将生成一个正在创建的数据库(以便创建数据库目录),然后该文件包括两个WAL dbname文件,后缀为-shm和-wal。

复制数据库时-wal和-shm文件与新数据库不匹配(它们属于覆盖的数据库)。

请参见此以获取修复程序A pre-populated database does not work at API 28 throws “no such table” exception

答案 2 :(得分:0)

显然,Android P设置了PRAGMA日志对象不同。仍然不知道是否会有副作用,但似乎正在起作用!

 @Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    db.disableWriteAheadLogging();
}