まず、私は似たような多くの質問を読んでいて、いくつかのアドバイスを受けて、私はstackoverflowユーザーに感謝します。JSONデータを使用してSQLiteから削除し、MySQLのリモートテーブルを同期させる
私はアプリケーションのiOS側でSQLiteに合計5つのデータベーステーブルを持ち、リモートサーバ用にMySQLで同等のデータベーステーブルを持っています。私はSQLiteのテーブルをプリロードしたデータを表示し、Appは期待通りに機能します。この問題は、iOSデバイスに保存されているローカル情報を置き換えるために、リモートデータベースからJSONデータをダウンロードするときに発生します。
// Create an object, reading its information from the local database.
Pregunta *objPregunta = [[Pregunta alloc] initWithPrimaryKey:0 database:delegate.database];
// Erase all data in the object's table (preguntas) see method below.
[objPregunta deleteAllFromDatabase];
// Obtain the remote objects retrieved via JSON, and cycle them.
NSArray *preguntas = (NSArray *)[responseDict objectForKey:@"preguntas"];
for (id pregunta in preguntas) {
// Create a dictionary storing the JSON object.
NSDictionary *pregunta_dict = (NSDictionary *) pregunta;
// Send the dictionary to the function for SQLite insertion.
[objPregunta insertNewRecordIntoDatabase:pregunta_dict];
}
// Free the object resources.
[objPregunta release];
これは上記のコードでPreguntaオブジェクトに関連付けられているSQLiteの削除機能である:私は、単一のテーブルを参照することで、それは簡単な維持されます
- (void) deleteAllFromDatabase {
if(delete_statement == nil) {
const char *sql = "DELETE FROM preguntas";
if (sqlite3_prepare_v2(database, sql, -1, &delete_statement, NULL) != SQLITE_OK) {
NSAssert1(0, @"Error: Failed to prepare SQL statement: %s.", sqlite3_errmsg(database));
}
}
if (sqlite3_step(delete_statement) != SQLITE_DONE) {
NSAssert1(0, @"Failed to save priority with message: %s.", sqlite3_errmsg(database));
}
sqlite3_reset(delete_statement);
}
そして最後に、これは関数でありますそれに渡された辞書オブジェクト使用して、データベースに新しいレコードを挿入します。今すぐ
- (void) insertNewRecordIntoDatabase:(NSDictionary *)pregunta_dict {
if (insert_statement == nil) {
const char *sql = "INSERT INTO preguntas (id_forma, numero, seccion, texto, respuesta, comentario, requiere_fotografia, fotografia, tipo) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)";
self.id_forma = [[pregunta_dict objectForKey:@"id_forma"] integerValue];
self.numero = [[pregunta_dict objectForKey:@"numero"] integerValue];
if([pregunta_dict objectForKey:@"seccion"] == [NSNull null]) {
self.seccion = nil;
} else {
self.seccion = [pregunta_dict objectForKey:@"seccion"];
}
self.texto = [pregunta_dict objectForKey:@"texto"];
if([pregunta_dict objectForKey:@"respuesta"] == [NSNull null]) {
self.respuesta = nil;
} else {
self.respuesta = [pregunta_dict objectForKey:@"respuesta"];
}
if([pregunta_dict objectForKey:@"comentario"] == [NSNull null]) {
self.comentario = nil;
} else {
self.comentario = [pregunta_dict objectForKey:@"comentario"];
}
self.requiere_fotografia = [pregunta_dict objectForKey:@"requiere_fotografia"];
if([pregunta_dict objectForKey:@"fotografia"] == [NSNull null]) {
self.fotografia = nil;
} else {
self.fotografia = [pregunta_dict objectForKey:@"fotografia"];
}
self.tipo = [pregunta_dict objectForKey:@"tipo"];
if (sqlite3_prepare_v2(database, sql, -1, &insert_statement, NULL) != SQLITE_OK) {
NSAssert1(0, @"Error: Failed to prepare SQL statement: %s.", sqlite3_errmsg(database));
} else {
@try {
sqlite3_bind_int (insert_statement, 1, self.id_forma);
sqlite3_bind_int (insert_statement, 2, self.numero);
sqlite3_bind_text(insert_statement, 3, [self.seccion UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 4, [self.texto UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 5, [self.respuesta UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 6, [self.comentario UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 7, [self.requiere_fotografia UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 8, [self.fotografia UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(insert_statement, 9, [self.tipo UTF8String], -1, SQLITE_TRANSIENT);
}
@catch (NSException *exception) {
;
}
}
}
if (sqlite3_step(insert_statement) != SQLITE_DONE) {
NSAssert1(0, @"Failed to prepare SQL statement: %s.", sqlite3_errmsg(database));
} else {
NSLog(@"Pregunta insert_id: %lld", sqlite3_last_insert_rowid(database));
}
sqlite3_reset(insert_statement);
}
を、コードの問題は何とかそれは間違って行を挿入しているようだ、ということですすべてのテーブルの削除/挿入プロセスが完了し、SQLiteから挿入されたデータを読み込むと、データベースに値が重複してしまいます。
私はそれがdeleteAllFromDatabase
機能と関係があると思っていましたが、もう一度それは問題を引き起こすほど簡単すぎるようです。プライマリキーに格納する値を直接指定しようとしましたが、制約が満たされていないためにアプリケーションがクラッシュします(外部キーはなく、各テーブルのプライマリキーのみです)。
あなたはどのような提案をしていますか?空のキャッチブロックを無視して、それらをテストしてコードを削除しました。ここで、私があなたのために公開するソース内のものを短くすることができます。また、ステートメントは、必要に応じて再利用してリセットするクラスのローカル静的変数です。
入力いただきありがとうございます。私が何をしているのかをよりよく理解するために、私があなたに必要とするかもしれない詳細を公開する予定です。
ここで私がキャッチするために管理してきたいくつかの調査結果です:
私はテーブルビュー内の行を表示しておりますので、私は、データベーステーブル内の すべての値があることがわかります( NSLogged)、プライマリキー( SQLite INTEGER AUTOINCREMENTによって自動生成されます)を除いて... が私の挿入ステートメントに間違っているか、または私がを送る方法を意味します挿入される各行の辞書データ。
限り、私はそれをインデント、文字列全体をキャプチャし、 それを情報の完全な整合性を確認するために表示され、それはすべての に一致していることと、すべての で何も問題はありませんJSONリソースのデータとしてリモートのMySQLテーブルのものです。コードの最初のブロックで
、foreachループを読み取ります
for (id pregunta in preguntas) {
しかしthis articleであなたは、彼らが(ポインタのためのように*で)代わりにfor (id *item in items) {
を使用しているでしょう。私はそれに似てしようとしたが、私はエラーが発生し、コードは何をコンパイルしません。それは以前の値が含まれませんので、私は何とか私は
insertNewRecordIntoDatabase:
関数に渡すDSDictionary
をリセットする必要があるだろうチャンスはありますか?私は、繰り返しごとにデータが異なると仮定しますが、これは私が間違っていることを証明しています。
フィードバックMundiさん、私はさらなる発見を反映するために私の質問を更新しました。 –
- プライマリキーが役立つかもしれません。 2つの同一レコードの主キーが隣接しているかどうか – Mundi
列がINTEGER PRIMARY KEY AUTOINCREMENTであるため、テーブル構造はプライマリキーを自動的に追加するように設定されています。新しいレコードを挿入するときにプライマリキーの列/値を設定しない...挿入はsqliteによって管理されます。 –