Android内のSQLiteデータベースに行を挿入しようとしています。私のDBにレコードを挿入するための呼び出しは次のようになります:DataHelper.insertChild(context、child)。私の目標は、静的に呼び出される関数に関数をラップして、すべての問題を処理することです。まず私のコードをあなたに教えてください。AndroidのSQLiteStatementの挿入。それ以降の呼び出しは失敗します
私は静的メソッドを使用して、これをやっている:
private static SQLiteDatabase prepareChildDatabase(Context context) {
Log.d(TAG, "DB: prepareChildDatabase");
OpenHelper openHelper = new OpenHelper(context);
return openHelper.getWritableDatabase();
}
その後、私は私の挿入を実行します。参照の場合
public static long insertChild(Context context, Child child) {
Log.d(TAG, "DB: insertChild");
SQLiteDatabase db = prepareChildDatabase(context);
SQLiteStatement insertStmt = db.compileStatement(INSERT);
insertStmt.bindLong(1, child.getBirthday().getTime());
// These are optional
if(child.getName() != null) {
insertStmt.bindString(2, child.getName());
} else {
insertStmt.bindNull(2);
}
if(child.getPhoto() != null) {
String photoUri = child.getPhoto().toString();
insertStmt.bindString(3, photoUri);
} else {
insertStmt.bindNull(3);
}
final long id = insertStmt.executeInsert();
// insertStmt.clearBindings(); // Not sure this is necessary
insertStmt.close();
db.close();
return id;
}
を、私OpenHelperはここにある:
private static class OpenHelper extends SQLiteOpenHelper {
OpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "DB: OpenHelper: onCreate: " + CREATE_CHILDREN_TABLE);
db.execSQL(CREATE_CHILDREN_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
そして最後に、変数、ステートメント、テーブル:
private static final String TABLE_NAME = "children";
private static final String COL_NAME = "name";
private static final String COL_BDAY = "birthday";
private static final String COL_PHOTO = "photo";
private static final String INSERT = "insert into "
+ TABLE_NAME + " ("
+ COL_BDAY + ", "
+ COL_NAME + ", "
+ COL_PHOTO + ") values (?, ?, ?)";
private static final String UPDATE = "update "
+ TABLE_NAME + "set "
+ COL_BDAY + " = ?, "
+ COL_NAME + " = ?, "
+ COL_PHOTO + " = ?) WHERE "
+ BaseColumns._ID + " = ?";
private static final String CREATE_CHILDREN_TABLE =
"CREATE TABLE " + TABLE_NAME + " ("
+ BaseColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ COL_BDAY + " INTEGER NOT NULL, "
+ COL_NAME + " TEXT NULL, "
+ COL_PHOTO + " TEXT NULL)";
だから何が起きているのかは、私が初めてこれをすべてうまく呼び出すということです。挿入作業、データがあり、私のSQLiteブラウザにDBをエクスポートすることができます。その後、insertChild(...)を呼び出すと、DBが破損します。 SQLiteBrowserにテーブルや行が表示されず、テキストエディタ内で開くといくつかのことが表示されます。私の推測は、DBが壊れているということです。行が挿入されていないため、読み込めません。 何もエラーはスローされません。
私はここで2つのことの1つを推測しています。まず、私のハンドルが正しく開閉しておらず、後の呼び出しでどこかの参照がボークされています。第二に、準備された声明の私の理解は間違っています。私はコードを見て、うまくいるようです。データベースを開き、プリペアドステートメントにバインドし、実行し、ステートメントを閉じ、データベースを閉じます。
誰もがこれで私を助けてくれるのですか?私はログに記録して、例外を探して、試してみましたが、何も動かないようです。私はちょっとした細部を見逃したかもしれないと思う。それとも私は狂ってしまいます。
おかげで、
マイク
更新
問題は私のエミュレータ上で再現していないので、私は、スレッドの方に私の注意を向けてきました。これらのリンクをチェックアウト:
http://www.kagii.com/journal/2010/9/10/android-sqlite-locking.html
android sqlite application is being forcefully closed on device
What are the best practices for SQLite on Android?
はい、挿入するたびに「読み書きに使用されるデータベースを作成および/または開く」というgetWritableDatabase()を呼び出します。ドキュメントに従って。これらの挿入はめったに呼び出されないので、DBを開いたり閉じたりするのは大丈夫です。私の関数prepareDatabase(...)を見てください。関数の開始時に呼び出され、接続を開きます。 – mhradek
prepareChildDatabaseとprepareDatabaseは同じですか? –
はい、私は物事をクリアするために子供を追加することを忘れました。編集されました。 – mhradek