データベースにレコードがあるかどうかを確認する必要があるAndroidアプリがあります。そうでない場合は、何かを処理して最終的に挿入し、データが存在する場合はデータベースからデータを読み取ります。 SQLiteOpenHelperのサブクラスを使用して、SQLiteDatabaseの書き換え可能なインスタンスを作成および取得します。テーブルが存在しない場合は、自動的にテーブルの作成を処理します(それを行うコードはonCreate(... ) 方法)。
ただし、テーブルがまだ存在せず、SQLiteDatabaseオブジェクトで最初に実行したメソッドがquery(...)の呼び出しである場合、logcatに「I/Database(26434):sqliteが返されました:error code = 1、msg = no such table:appdata "、そして確かに、appdataテーブルは作成されていません。
理由についてのアイデアはありますか?
テーブルが存在するかどうかをテストする方法を探しています(存在しない場合、データは確かに含まれていないため、書き込むまでテーブルを作成する必要はありません)適切に)、またはクエリの最初の呼び出しに間に合うように作成され、空になっていることを確認する方法(...)
編集
これは、以下の2つの回答の後に投稿されました。
問題が見つかった可能性があります。何らかの理由で、両方が同じデータベースファイルにアクセスしている場合でも、各テーブルに異なるSQLiteOpenHelperを作成することにしました。そのコードをリファクタリングして、1つのOpenHelperのみを使用し、onCreate内に両方のテーブルを作成すると、うまく機能すると思います...
はい、私の編集の理論は正しかったことがわかりました:onCreateメソッドが実行されない原因は、SQLiteOpenHelper
オブジェクトがデータベースを参照し、各テーブルに個別のオブジェクトを持たないという事実でした。両方のテーブルを1つのSQLiteOpenHelper
にパックすると、問題が解決しました。
これを試してください:
public boolean isTableExists(String tableName, boolean openDb) {
if(openDb) {
if(mDatabase == null || !mDatabase.isOpen()) {
mDatabase = getReadableDatabase();
}
if(!mDatabase.isReadOnly()) {
mDatabase.close();
mDatabase = getReadableDatabase();
}
}
Cursor cursor = mDatabase.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'", null);
if(cursor!=null) {
if(cursor.getCount()>0) {
cursor.close();
return true;
}
cursor.close();
}
return false;
}
Android SQLite APIについては何も知りませんが、SQLで直接話すことができる場合、これを行うことができます。
create table if not exists mytable (col1 type, col2 type);
これにより、テーブルが常に作成され、既に存在する場合はエラーがスローされなくなります。
これは私がやったことです:
/* open database, if doesn't exist, create it */
SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null);
Cursor c = null;
boolean tableExists = false;
/* get cursor on it */
try
{
c = mDatabase.query("tbl_example", null,
null, null, null, null, null);
tableExists = true;
}
catch (Exception e) {
/* fail */
Log.d(TAG, tblNameIn+" doesn't exist :(((");
}
return tableExists;
この質問にはすでに多くの良い答えがありますが、もっと簡単だと思う別の解決策を思いつきました。 tryブロックと次のcatchでクエリを囲みます。
catch (SQLiteException e){
if (e.getMessage().contains("no such table")){
Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" );
// create table
// re-run query, etc.
}
}
それは私のために働いた!
// @param db, readable database from SQLiteOpenHelper
public boolean doesTableExist(SQLiteDatabase db, String tableName) {
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.close();
return true;
}
cursor.close();
}
return false;
}
SQLiteOpenHelper
を拡張するクラスを作成し、onCreate
メソッドを実装したことを述べました。そのクラスですべてのデータベース取得呼び出しを実行していることを確認していますか? SQLiteOpenHelper#getWritableDatabase
およびSQLiteDatabase
を介してのみgetReadableDatabase
オブジェクトを取得する必要があります。そうしないと、必要なときにonCreate
メソッドが呼び出されません。もしそれをしているなら、代わりにSQLiteOpenHelper#onUpgrade
メソッドが呼び出されているかどうかを確認してください。その場合、データベースのバージョン番号はある時点で変更されましたが、それが発生したときにテーブルが適切に作成されませんでした。
余談ですが、データベースへのすべての接続を閉じてContext#deleteDatabase
を呼び出し、SQLiteOpenHelper
を使用して新しいdbオブジェクトを取得することにより、データベースの再作成を強制できます。
no such table exists: error
が来るのは、同じデータベースにテーブルを作成するたびに1つのテーブルでデータベースを作成すると、このエラーが発生するためです。
このエラーを解決するには、新しいデータベースを作成する必要があり、onCreate()メソッド内で同じデータベースに複数のテーブルを作成できます。
Important条件はIF NOT EXISTSテーブルがすでに存在するかデータベースにないかをチェックする
好む...
String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "("
+ KEY_PLAYER_ID + " TEXT,"
+ KEY_PLAYER_IMAGE + " TEXT)";
db.execSQL(query);
public boolean isTableExists(String tableName) {
boolean isExist = false;
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
if (cursor != null) {
if (cursor.getCount() > 0) {
isExist = true;
}
cursor.close();
}
return isExist;
}