“找不到表” 错误在 Android 9 及以下版本中使用现有数据库时发生。

huangapple go评论79阅读模式
英文:

"No such table" Error using an existing database in Android 9 and below

问题

我正在尝试在Android Studio中使用现有的SQLite数据库。在Android 10+中可以正常工作,但在Android 9及以下版本中出现以下错误:

没有这个表

DatabaseHelper 类:

package com.example.testlocaldatabase;

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

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

public class DatabaseHelper extends SQLiteOpenHelper {

  private static String DB_NAME = "myDatabase.SqLite";
  private static String DB_PATH = "";
  private static int DB_VERSION = 1;

  private SQLiteDatabase database;
  private Context context;
  private boolean needUpdate = false;

  public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    if (Build.VERSION.SDK_INT >= 17) {
      DB_PATH = context.getApplicationInfo().dataDir + "/databases/";

    } else {
      DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    }
    this.context = context;
    copyDatabase();
    this.getReadableDatabase();
  }

  @Override
  public void onCreate(SQLiteDatabase sqLiteDatabase) {

  }

  @Override
  public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    if (i1 > i) {
      needUpdate = true;
    }

  }

  private void copyDatabase() {

    if (!checkDatabase()) {
      this.getReadableDatabase();
      this.close();
      try {
        copyDBFile();
      } catch (IOException e) {
        throw new Error("Error copying database");
      }//catch
    }//if
  }//copyDatabase

  private boolean checkDatabase() {
    File dbFile = new File(DB_PATH + DB_NAME);
    if (dbFile.exists()) {
      return true;
    } else {
      return false;
    }
  }

  private void copyDBFile() throws IOException {
    InputStream inputStream = context.getAssets().open(DB_NAME);
    OutputStream outputStream = new FileOutputStream(DB_PATH + DB_NAME);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) > 0) {
      outputStream.write(buffer, 0, length);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
  }

  public void updateDatabase() throws IOException {
    if (needUpdate) {
      File dbFile = new File(DB_PATH + DB_NAME);
      if (dbFile.exists())
        dbFile.delete();
      copyDatabase();
      needUpdate = false;

    }//if
  }//updateDatabase

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

  }
}

MainActivity:

package com.example.testlocaldatabase;

import androidx.appcompat.app.AppCompatActivity;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

  private DatabaseHelper databaseHelper;
  private SQLiteDatabase database;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    databaseHelper = new DatabaseHelper(MainActivity.this);
    try {
      databaseHelper.updateDatabase();
    } catch (IOException e) {
      e.printStackTrace();
    }
    database = databaseHelper.getReadableDatabase();

    // 从数据库中提取数据
    Cursor cursor = database.rawQuery("select * from drugs", null);
    while (cursor.moveToNext()) {
      String b = cursor.getString(cursor.getColumnIndexOrThrow("drugName"));
      Log.i("LOG", "" + b);
    }
    cursor.close();

  }

}

在日志中的错误行:

android.database.sqlite.SQLiteException: no such table: drugs (code 1 SQLITE_ERROR): , while compiling: select * from drugs

英文:

I'm trying to use an existing SQLite database in Android Studio. It works in Android 10+ but in Android 9 and below I get this error:

> No such table

DatabaseHelper class:

package com.example.testlocaldatabase;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class DatabaseHelper extends SQLiteOpenHelper {
private static String DB_NAME = "myDatabase.SqLite";
private static String DB_PATH = "";
private static int DB_VERSION = 1;
private SQLiteDatabase database;
private Context context;
private boolean needUpdate = false;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
if (Build.VERSION.SDK_INT >= 17) {
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
this.context = context;
copyDatabase();
this.getReadableDatabase();
}
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
}
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
if (i1 > i) {
needUpdate = true;
}
}
private void copyDatabase() {
if (!checkDatabase()) {
this.getReadableDatabase();
this.close();
try {
copyDBFile();
} catch (IOException e) {
throw new Error("Error copying database");
}//catch
}//if
}//copyDatabase
private boolean checkDatabase() {
File dbFile = new File(DB_PATH + DB_NAME);
if (dbFile.exists()) {
return true;
} else {
return false;
}
}
private void copyDBFile() throws IOException {
InputStream inputStream = context.getAssets().open(DB_NAME);
OutputStream outputStream = new FileOutputStream(DB_PATH + DB_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
}
public void updateDatabase() throws IOException {
if (needUpdate) {
File dbFile = new File(DB_PATH + DB_NAME);
if (dbFile.exists())
dbFile.delete();
copyDatabase();
needUpdate = false;
}//if
}//updateDatabase
@Override
public synchronized void close() {
if (database != null) {
database.close();
}
super.close();
}
}

MainActivity :

package com.example.testlocaldatabase;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private DatabaseHelper databaseHelper;
private SQLiteDatabase database;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseHelper = new DatabaseHelper(MainActivity.this);
try {
databaseHelper.updateDatabase();
} catch (IOException e) {
e.printStackTrace();
}
database = databaseHelper.getReadableDatabase();
// pull out data from database
Cursor cursor = database.rawQuery("select * from drugs", null);
while (cursor.moveToNext()) {
String b = cursor.getString(cursor.getColumnIndexOrThrow("drugName"));
Log.i("LOG", "" + b);
}
cursor.close();
}
}

Error line in logcat :

> android.database.sqlite.SQLiteException: no such table: drugs (code 1 SQLITE_ERROR): , while compiling: select * from drugs

答案1

得分: 1

在Android 13上,每当您在数据库模式中进行任何更改时,都需要更新数据库版本。

public class DatabaseHelper extends SQLiteOpenHelper {

  private static String DB_NAME = "myDatabase.SqLite";
  private static String DB_PATH = "";
  private static int DB_VERSION = 2;

  private SQLiteDatabase database;
  private Context context;
  private boolean needUpdate = false;

  public DatabaseHelper(Context context) {
    super(context, DB_NAME, null, DB_VERSION);
    if (Build.VERSION.SDK_INT >= 17) {
      DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
    } else {
      DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
    }
    this.context = context;
    copyDatabase();
    this.getReadableDatabase();
  }
}
英文:

On android 13 every time you need to update the database version when you have done any changes in DB schema.

public class DatabaseHelper extends SQLiteOpenHelper {
private static String DB_NAME = "myDatabase.SqLite";
private static String DB_PATH = "";
private static int DB_VERSION = 2;
private SQLiteDatabase database;
private Context context;
private boolean needUpdate = false;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
if (Build.VERSION.SDK_INT >= 17) {
DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
} else {
DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
}
this.context = context;
copyDatabase();
this.getReadableDatabase();
}

huangapple
  • 本文由 发表于 2023年7月31日 23:15:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76804972.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定