SQLite 数据库中没有这样的 table

no such table in SQLite db

我是 android 应用程序编程的菜鸟。使用 SQLite 数据库时出现以下问题:

Logcat 告诉我:“没有这样的 table: table1”,当我 运行 这两种方法时。我的错误在哪里?

我使用现有的数据库,放在 assets/databases 文件夹中。

MainActivity

    public void onClickSearch(View view) {
        dataBaseHelper = new DataBaseHelper(MainActivity.this);
        try {
            String post = dataBaseHelper.getPost("table1","user");
            Toast.makeText(this,String.format("%s",post),Toast.LENGTH_SHORT).show();
        }catch (Exception e){
            Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
        }
    }
   public void onClickRows(View view) {
        dataBaseHelper = new DataBaseHelper(MainActivity.this);
        try {
            long count = dataBaseHelper.numberOfRows("table1");
            String message = String.format("%s",count);
            Toast.makeText(MainActivity.this,message,Toast.LENGTH_LONG).show();
        }catch (Exception e){
            Toast.makeText(this,"Error",Toast.LENGTH_SHORT).show();
        }
    }

DataBaseHelper

public class DataBaseHelper extends SQLiteOpenHelper {

    public DataBaseHelper(@Nullable Context context) {
        super(context, "database.db", null, 1);
    }
    public String getPost(String table, String nameIn){
        String queryString = "SELECT post FROM "+ table +" WHERE name = "+nameIn;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(queryString,null);
        StringBuffer buffer = new StringBuffer();
        while(cursor.moveToNext()){
            String post = cursor.getString(0);
            buffer.append(""+post);
        }
        cursor.close();
        db.close();
        return buffer.toString();
    }
    public long numberOfRows(String table){
        String queryString = "SELECT * FROM " + table;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(queryString,null);
        long count = cursor.getCount();
        cursor.close();
        db.close();
        return count;
    }
}

当我从设备文件资源管理器导出 .db 文件时,该文件是空的(只是一个 android_manifest table)。

资产文件夹中我的文件在哪里?

请帮忙。

Where is my file from the assets folder?

从外观上看,它原封不动地放在包裹里。需要将数据库从包中复制并解压到可以使用的位置。

只有 android_manifest table 的空数据库表示正在创建数据库,因为 getReadableDatabase(或 getWriteableDatabase)将尝试这样做。

正在解决问题

简而言之,通常所做的是在尝试访问数据库时检查数据库是否存在,如果不存在,则复制数据库并从包中解压缩。

  • 如果数据库存在则使用它(因此为什么下面需要删除已创建的空数据库)

以下是包含上述内容的 DataBaseHelper class 的修改版本。我建议您阅读评论(假设 onCreate 和 onUpgrade 方法存在并且在您发布的代码中被省略)。

注意 更改代码后,您需要删除已创建的数据库。 在重新运行前卸载 应用程序将删除现有数据库。

注意 你说:-

I use an existing database, placed in assets/databases folder.

当现有数据库位于资产文件夹而不是 assets/databases 文件夹中时,下面的代码有效。 您应该将数据库移动或复制到资产文件夹。

public class DataBaseHelper extends SQLiteOpenHelper {

    //######## ADDED (more convenient to code in one place)
    static String DATABASE_NAME = "database.db";

    public DataBaseHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, 1);
        String databasePath = context.getDatabasePath(DATABASE_NAME).getPath();
        if (!doesDatabaseExist(databasePath)) {
            copyDatabaseFromAssets(context,databasePath,DATABASE_NAME);
        }
    }


    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }

    //######## ADDED
    /*
        Check to see if the database exists.
        If it does then return, otherwise check to see
        if the directories in the path exist, if they do
        return, otherwise make the missing directories.
     */
    private boolean doesDatabaseExist(String databasepath) {
        if (new File(databasepath).exists()) return true;
        if (new File(databasepath).getParentFile().exists()) return false;
        new File(databasepath).getParentFile().mkdirs();
        return false;
    }

    //######## ADDED
    /*
        Copy the database from the assets folder
     */
    private void copyDatabaseFromAssets(Context context, String databasepath, String assetfilename) {
        int bSize = 4096, bytes = 0;
        byte[] buffer = new byte[bSize];
        try {
            InputStream asset = context.getAssets().open(assetfilename);
            FileOutputStream database = new FileOutputStream(new File(databasepath));
            while((bytes = asset.read(buffer)) > 0) {
                database.write(buffer,0,bytes);
            }
            database.flush();
            database.close();
            asset.close();

        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("Error copy Asset File " + assetfilename + " to " + databasepath);
        }
    }

    public String getPost(String table, String nameIn){
        String queryString = "SELECT post FROM "+ table +" WHERE name = "+nameIn;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(queryString,null);
        StringBuffer buffer = new StringBuffer();
        while(cursor.moveToNext()){
            String post = cursor.getString(0);
            buffer.append(""+post);
        }
        cursor.close();
        db.close();
        return buffer.toString();
    }
    public long numberOfRows(String table){
        String queryString = "SELECT * FROM " + table;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(queryString,null);
        long count = cursor.getCount();
        cursor.close();
        db.close();
        return count;
    }
}