私はSQLiteとデータベースをAndroidで始めています。この問題を見つけました。同様の質問をたくさん読みましたが、まだ解決策が見つかりませんでした。
これは私が得ているエラーです:
E/AndroidRuntime(529):原因:Android.database.sqlite.SQLiteException:no such table:ligas_bd:、コンパイル中:SELECT * FROM ligas_bd
これは私のコードです。
DBHelper myDbHelper = new DBHelper(this);
myDbHelper = new DBHelper(this);
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.open();
SQLiteDatabase db = null;
db = myDbHelper.getWritableDatabase();
String[] args = new String[] {""};
Cursor c = db.rawQuery(" SELECT * FROM ligas_bd", args); <---- Error in this line
if (c.moveToFirst()) {
do {
String cod = c.getString(0);
String nombre = c.getString(1);
String flag = c.getString(0);
String cod_url = c.getString(0);
ligas.add(new Item_Liga(nombre, flag, cod, cod_url));
} while(c.moveToNext());
}
}catch(SQLException sqle){
throw sqle;
}
DBHelper.Java
public class DBHelper extends SQLiteOpenHelper{
private static String DB_NAME = "ligas_bd";
private SQLiteDatabase myDataBase;
private final Context myContext;
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException{
boolean dbExist = checkDataBase();
if(dbExist){ }
else {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copiando Base de Datos");
}
}
}
private boolean checkDataBase(){
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch(SQLiteException e) { }
if(checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException{
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
OutputStream myOutput = new FileOutputStream(outFileName);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer))>0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
public void open() throws SQLException{
try {
createDataBase();
} catch (IOException e) {
throw new Error("Ha sido imposible crear la Base de Datos");
}
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
@Override
public void onCreate(SQLiteDatabase db) { }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }
また、ルートエクスプローラーのdata/data/mypackagename/databasesを使用して携帯電話をチェックインすると、データベースは通常どおり表示されます。
このデータベースとメインテーブルの名前は同じです。SQLiteデータベースブラウザーの次の写真をご覧ください。
私はテーブルを作成しているのではなく、SQLite Database Browserを使用する前にテーブルを作成し、そこから読み取ろうとしています。
方法はわかりませんが、最終的に修正しました。今度は このチュートリアル に続いて再び始めました。それが役に立てば幸い!
これは推測に過ぎませんが、3つの可能性がここで起こっていることがわかります...
this.getReadableDatabase()
メソッドでcreateDatabase()
を呼び出すと、自動的に空のデータベースが作成されます。assets
フォルダーから作成済みのデータベースをコピーしようとして失敗したか、データベースが間違った場所にコピーされています。db.rawQuery(...)
を呼び出したときにクエリされるデータベースです。さらに説明するには、 SQLiteOpenHelper のソースを見ると便利です。
SQLiteOpenHelper
のインスタンスを作成すると、データベース名やバージョンなどが設定されますが、データベースは作成されません。代わりに、getReadableDatabase()
またはgetWritableDatabase()
の最初の呼び出しは、データベースが存在するかどうかを確認し、存在しない場合は作成します。空のデータベースを作成した後、onCreate(...)
メソッドが呼び出されますが、この場合は何もしません。
ポイント2(上記)-_DB_PATH
_は_/data/data/mypackagename/databases
_と言います。本当にそうで、末尾に_/
_がない場合は、次の行を...
_String myPath = DB_PATH + DB_NAME;
_
... myPath
を_/data/data/mypackagename/databasesligas_db
_に設定します。その場合、assets
からのコピーが成功したとしても、コピーされたデータベースは期待した場所にはなりません。
最後にポイント3(上記)でdb.rawQuery(...)
を呼び出すと、db
が指すインスタンスは、以前のgetWritableDatabase()
の呼び出しによって返されます。 assets
からのコピーが失敗したか、間違ったパスにコピーされたと仮定すると、db
はステップ1で作成された空のデータベースを指します。
表示されるエラーは、テーブルが存在せず、データベースが存在しないことを示すエラーではないことです-唯一の論理的な説明は、コピー元のデータベースではなく空のデータベースでクエリを実行していることですassets
。
編集:私が言及したいもう一つのこと。 Androidディレクトリのいずれかにハードコードされたパスを使用することはお勧めできません。たとえば、ほとんどのデバイスでは、データベースが作成されるディレクトリは_/data/data/<package-name>/databases
_になりますが、これは保証ではありません。 Androidが使用するデータベースディレクトリへのパスを取得するために使用できるFile
オブジェクトを返すため、getDatabasePath(...)
メソッドを呼び出すと、はるかに安全です。データベースクラス。
同じ問題が発生したため、プロジェクトをクリーンアップし、テストデバイスからアプリを削除して再インストールすることで修正しました。誤って空のデータベースを作成した別のチュートリアルを実行したために発生したと考えています。修正されたコードは、古い空のデータベースを取得していました。
デバイスでアプリを実行している場合は、>>設定(Androidデバイス)>>>アプリケーション>>>アプリケーションの検索>>データとキャッシュをクリアします。その後、デバッグに移動します。または、新しいアプリケーションを再インストールします。
私はそれをすることでこの問題を解決しました...
例外は非常に明確で、データベース(ligas_db)を作成しましたが、その中にテーブルは作成していません(そのようなテーブル例外はありません= ligas_dbという名前のテーブルはありません)
これを確認してください: http://www.vogella.de/articles/AndroidSQLite/article.html
(¿Eres Antonio Recio?jaja)
ファイル名に.db拡張子を含めると同じ問題が発生しました:
private static String DB_NAME = "ligas_bd.db";
あなたが持っている ligas_bd
をデータベースの名前として使用し、SELECT
から取得しようとしています。
私の問題は、パス名の末尾に「/ databases /」を残したことです。私にとって非常に紛らわしかったのは、dbconnectionをロードしてインスタンス変数として保存する前に動作していたコードです。次に、getReadableDatabase()メソッドとgetWritableDatabase()メソッドを使用する必要があるとき、「実際の」データベースパスに作成された空のデータベースを引き込み続けました。
誤り/ data/data/mypackagename /
正しい/ data/data/mypackagename/databases /
答えの@Squonkに+1することで、ついにこれを追跡することができました!
テーブルを選択する前に、まずテーブルを作成する必要があります。以前に作成したことがありますが、データベース接続を開いた後に作成する必要があります。