SQLiteステートメントINSERT OR REPLACE INTO
は、行がすでに存在する場合はその行を置き換えます。しかし、同じステートメントを何度も実行すると、置換ではなく挿入を続けます。
どのような場合にREPLACEが実際に発生しますか?
INSERT OR REPLACE INTO names (rollno, name) VALUES (1, "Adam")
挿入する行のPRIMARYKEYがテーブル内の別の行と同じである場合、置換が発生します。主キーを定義するのを忘れた可能性があります。
ドキュメントUNIQUE
で説明されているように、違反が発生した場合、値はいくつかの行で置き換えられます。
UNIQUE制約違反が発生すると、REPLACEアルゴリズムは、現在の行を挿入または更新する前に、制約違反の原因となっている既存の行を削除し、コマンドは通常どおり実行を継続します。NOT NULL制約違反が発生した場合、REPLACE競合解決により、NULL値がその列のデフォルト値に置き換えられます。列にデフォルト値がない場合は、ABORTアルゴリズムが使用されます。CHECK制約違反が発生した場合、REPLACE競合解決アルゴリズムは常にABORTのように機能します。
作成する列UNIQUE
は。だと思いますrollno
。PRIMARY KEY
それをテーブルのようにするか、単にUNIQUE
制約を作成することによって、それを一意にすることができます。
ははは、あら、どこから始めたらいいの?
このSQL地獄を経験したとき、私はコンピューターを罵倒していました。
ありがたいことに、私はそれをうまく動かすことができました!:D
INSERT OR REPLACE INTOステートメントで私が学んだことの1つは、1つの非常に重要なことを行う必要があるということです。
Mark one column of your table as "UNIQUE" during SQL table creation.
次に例を示します(右端までスクロールします)。
NSString *strEvents = @"CREATE TABLE Events (eventid INTEGER PRIMARY KEY, nodeID INTEGER, title VARCHAR(255), description TEXT, eventTime VARCHAR(255), eventDate VARCHAR(255), eventLocation VARCHAR(255), imagePaths TEXT, bookingURL TEXT, UNIQUE(nodeID));";
上記の例では、「nodeID」列を一意としてマークしています。
これを行うと、次のように使用できます。
-(void)batchSaveEvents:(NSMutableArray *)paramList
{
@synchronized(self)
{
if(self.isConnected == YES)
{
const char *sql = "INSERT OR REPLACE INTO Events (nodeID,title,description,eventTime,eventDate,eventLocation,imagePaths,bookingURL) VALUES (?,?,?,?,?,?,?,?);";
sqlite3_stmt *stmtSave;
if(sqlite3_prepare(objDatabase, sql, -1, &stmtSave, NULL) != SQLITE_OK)
{
//NSLog(@"FAILED %s", sqlite3_errmsg(objDatabase));
return;
}
int listIndex = 0;
sqlite3_exec(objDatabase, "BEGIN IMMEDIATE TRANSACTION", 0, 0, 0); // Begin Trasaction
for(listIndex = 0; listIndex < [paramList count]; listIndex++)
{
sqlite3_bind_int(stmtSave, 1, [[(Event *)[paramList objectAtIndex:listIndex] nodeID] intValue]);
sqlite3_bind_text(stmtSave, 2, [[(Event *)[paramList objectAtIndex:listIndex] title] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 3, [[(Event *)[paramList objectAtIndex:listIndex] description] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 4, [[(Event *)[paramList objectAtIndex:listIndex] eventTime] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 5, [[(Event *)[paramList objectAtIndex:listIndex] eventDate] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 6, [[(Event *)[paramList objectAtIndex:listIndex] eventLocation] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 7, [[(Event *)[paramList objectAtIndex:listIndex] imagePaths] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_bind_text(stmtSave, 8, [[(Event *)[paramList objectAtIndex:listIndex] bookingURL] UTF8String], -1, SQLITE_TRANSIENT);
sqlite3_step(stmtSave);
sqlite3_reset(stmtSave);
}
sqlite3_exec(objDatabase, "COMMIT", 0, 0, 0); // Commit Transaction
sqlite3_finalize(stmtSave);
}
}
}
頑張ってください!...またはシスタ!