2

SQLiteステートメントINSERT OR REPLACE INTOは、行がすでに存在する場合はその行を置き換えます。しかし、同じステートメントを何度も実行すると、置換ではなく挿入を続けます。

どのような場合にREPLACEが実際に発生しますか?

INSERT OR REPLACE INTO names (rollno, name) VALUES (1, "Adam")
4

3 に答える 3

6

挿入する行のPRIMARYKEYがテーブル内の別の行と同じである場合、置換が発生します。主キーを定義するのを忘れた可能性があります。

于 2012-08-30T07:44:01.870 に答える
3

ドキュメントUNIQUEで説明されているように、違反が発生した場合、値はいくつかの行で置き換えられます。

UNIQUE制約違反が発生すると、REPLACEアルゴリズムは、現在の行を挿入または更新する前に、制約違反の原因となっている既存の行を削除し、コマンドは通常どおり実行を継続します。NOT NULL制約違反が発生した場合、REPLACE競合解決により、NULL値がその列のデフォルト値に置き換えられます。列にデフォルト値がない場合は、ABORTアルゴリズムが使用されます。CHECK制約違反が発生した場合、REPLACE競合解決アルゴリズムは常にABORTのように機能します。

作成する列UNIQUEは。だと思いますrollnoPRIMARY KEYそれをテーブルのようにするか、単にUNIQUE制約を作成することによって、それを一意にすることができます。

于 2012-08-30T10:22:46.263 に答える
1

ははは、あら、どこから始めたらいいの?

この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);
        }
    }
}

頑張ってください!...またはシスタ!

于 2012-08-30T09:00:00.447 に答える