造成原因:android.database.sqlite.SQLiteException:否这样的表:BOOK(代码1 SQLITE_ERROR)

时间:2018-09-14 04:51:46

标签: android android-sqlite android-9.0-pie

我们已经创建了xyz.sqlite文件(在其中具有名为BOOK的表),并将其保存到“ raw”文件夹中,然后在运行时复制该文件并创建数据库,在所有版本的android到Android8。但是,当我在模拟器上的Android 9(Pie)上运行它时,它给了我下面提到的错误...

搜索了解决方案,但无济于事...任何帮助将不胜感激...

谢谢。

09-13 00:55:49.536 5685-5685/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             Process: com.kosmos.zentrale, PID: 5685
                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kosmos.zentrale/com.kosmos.zentrale.CatalogNew}: android.database.sqlite.SQLiteException: no such table: BOOK (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM BOOK ORDER BY _erscheinungsjahr DESC  , _uniqueID ASC
                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
                                                 at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
                                                 at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
                                                 at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
                                                 at android.os.Handler.dispatchMessage(Handler.java:106)
                                                 at android.os.Looper.loop(Looper.java:193)
                                                 at android.app.ActivityThread.main(ActivityThread.java:6669)
                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
                                              Caused by: android.database.sqlite.SQLiteException: no such table: BOOK (code 1 SQLITE_ERROR): , while compiling: SELECT * FROM BOOK ORDER BY _erscheinungsjahr DESC  , _uniqueID ASC
                                                 at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                 at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
                                                 at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
                                                 at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                 at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                 at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                 at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
                                                 at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1408)
                                                 at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1255)
                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1126)
                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1294)
                                                 at com.mobisys.android.database.BookDatabase.query(BookDatabase.java:68)
                                                 at com.mobisys.android.database.HelperDatabase.getBooks(HelperDatabase.java:57)
                                                 at com.kosmos.zentrale.CatalogNew.setCursorAdapter(CatalogNew.java:617)
                                                 at com.kosmos.zentrale.CatalogNew.onCreate(CatalogNew.java:120)
                                                 at android.app.Activity.performCreate(Activity.java:7136)
                                                 at android.app.Activity.performCreate(Activity.java:7127)
                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
                                                 at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
                                                 at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
                                                 at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
                                                 at android.os.Handler.dispatchMessage(Handler.java:106) 
                                                 at android.os.Looper.loop(Looper.java:193) 
                                                 at android.app.ActivityThread.main(ActivityThread.java:6669) 
                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                 at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 

下面是我们的数据库创建代码

public class BookDatabase {
public static final String DATABASE_NAME = "xyz.sqlite";
public static final int DATABASE_VERSION = 2;
private static String DB_PATH = "/data/data/"+"/databases/";
private OpenHelper gameHelper;
private SQLiteDatabase database;

public BookDatabase(Context context){
    try {
        DB_PATH = "/data/data/"+context.getPackageName()+"/databases/";
        gameHelper=new OpenHelper(context);
        gameHelper.createDataBase();
        openDataBase();
    } catch (IOException e) {
        gameHelper=null;
        e.printStackTrace();
    }
    catch (SQLException e) {
        gameHelper=null;
        e.printStackTrace();
    }
}

public void openDataBase() throws SQLException{
    //Open the database
    String myPath = DB_PATH + DATABASE_NAME;
    database = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}


public long insert(String table, ContentValues values){
    return database.insert(table, null, values);
}

public long delete(String table, String where, String[] whereArgs){
    return database.delete(table, where, whereArgs);
}

public int update(String table, ContentValues values, String whereClause, String[] whereArgs){
    return database.update(table, values, whereClause, whereArgs);
}

public long countRows(String query){
    return DatabaseUtils.longForQuery(database, query, null);
}

public Cursor query(String table,String[] columns, String selection,String[] selectionArgs,String groupBy,String having,String orderBy){
    return database.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
}

public void close(){
    database.close();
    gameHelper.close();
}

public Cursor rawQuery(String sql,String[] args){
    return database.rawQuery(sql, args);
}

private class OpenHelper extends SQLiteOpenHelper {
    Context context;

    OpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context=context;
    }

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

        boolean dbExist = checkDataBase();

        if(dbExist){

            //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");

            }


        }



    }

    /**
     * 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(){

        try{
            File databasePath = context.getDatabasePath(DATABASE_NAME);
            return databasePath.exists();
        }catch(Exception e){
            return false;
        }

    }

    /**
     * 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 transfering bytestream.
     * */
    private void copyDataBase() throws IOException{

        //Open your local db as the input stream
        InputStream myInput = context.getResources().openRawResource(R.raw.xyz);

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

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

        //transfer bytes from the inputfile to the outputfile
        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();

    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
    }

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

}

}

4 个答案:

答案 0 :(得分:2)

我在应用程序中所做的完全相同,创建一个“ my_db.sql”->将其保存到“ raw”文件夹中,然后将其复制并在运行时创建数据库。

我有同样的问题。该应用程序似乎在Pie之外的所有较低版本的Android上均可正常运行。经过深思熟虑和分析,对我有用的是添加一行代码“ db.disableWriteAheadLogging();”。在“ onOpen()”方法中。

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

答案 1 :(得分:1)

如果您确定数据库的完整性和代码的正确性,那么最可能导致此错误的原因可能是因为资产文件是在构建APK时压缩的。

要禁用数据库文件的自动压缩,请在android块内的app build.gradle文件中包含以下代码段。

aaptOptions {
   noCompress 'db'
}

希望这可以解决您的问题...

答案 2 :(得分:1)

这是我的工作方式...更改了整个班级的结构...下面是编辑后的新班级...

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;


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

public class BookDatabase extends SQLiteOpenHelper {
private static String DB_NAME = "xyz.db";
private static String DB_PATH = "";
private static final int DB_VERSION = 1;

private SQLiteDatabase mDataBase;
private final Context mContext;
private boolean mNeedUpdate = false;

public BookDatabase(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    if (android.os.Build.VERSION.SDK_INT >= 17)
        DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    else
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    this.mContext = context;

    copyDataBase();

    this.getReadableDatabase();
}

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

        copyDataBase();

        mNeedUpdate = false;
    }
}


public int update(String table, ContentValues values, String whereClause, String[] whereArgs){
    SQLiteDatabase mDataBase = this.getWritableDatabase();
    return mDataBase.update(table, values, whereClause, whereArgs);
}

public long countRows(String query){
    SQLiteDatabase db = this.getWritableDatabase();

    return DatabaseUtils.longForQuery(db, query, null);
}

public long insert(String table, ContentValues values){

    SQLiteDatabase db = this.getWritableDatabase();

    return db.insert(table, null, values);
}

public long delete(String table, String where, String[] whereArgs){
    SQLiteDatabase mDataBase = this.getWritableDatabase();
    return mDataBase.delete(table, where, whereArgs);
}

public Cursor rawQuery(String sql,String[] args){
    SQLiteDatabase mDataBase = this.getWritableDatabase();
    return mDataBase.rawQuery(sql, args);
}


public Cursor query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy){

    SQLiteDatabase db = this.getWritableDatabase();

    return db.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);
}

private boolean checkDataBase() {
    File dbFile = new File(DB_PATH + DB_NAME);
    return dbFile.exists();
}

private void copyDataBase() {
    if (!checkDataBase()) {
        this.getReadableDatabase();
        this.close();
        try {
            copyDBFile();
        } catch (IOException mIOException) {
            throw new Error("ErrorCopyingDataBase");
        }
    }
}

private void copyDBFile() throws IOException {
    //InputStream mInput = mContext.getAssets().open(DB_NAME);
    InputStream mInput = mContext.getResources().openRawResource(R.raw.xyz);
    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 boolean openDataBase() throws SQLException {
    mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
    return mDataBase != null;
}

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

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (newVersion > oldVersion)
        mNeedUpdate = true;
}
}

答案 3 :(得分:0)

在SQLiteOpenHelper类上使用以下方法

@Override
public void onOpen(SQLiteDatabase db) {
    super.onOpen(db);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        db.disableWriteAheadLogging();
    }
}