2012-08-30 59 views
2

SQLite語句INSERT OR REPLACE INTO將替換行,如果它已經存在。但是當我一次又一次地運行相同的語句時,它會一直插入而不是替換。SQLite語句INSERT OR REPLACE INTO not clear to me

REPLACE實際發生在什麼情況下?

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

回答

6

如果要插入的行與表中的另一個PRIMARY KEY具有相同的PRIMARY KEY,則會發生替換。 你可能忘了定義一個主鍵。

+4

或者有一個主鍵是自動增量('id'或其他),你不在你的查詢中。它會得到一個新的'id',所以它永遠不會重複。 – Nanne

1

哈哈哈,哦,男人我從哪裏開始?

我在通過這個SQL地獄時詛咒電腦。

謝天謝地,我設法讓它工作! :d

一兩件事,我用INSERT瞭解到OR REPLACE INTO說法是,你需要做一個超臨界件事:

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

好運brudda! ...或sista!

3

值將在某行更換如果發生UNIQUE違規行爲,如documentation解釋:

當一個UNIQUE限制衝突發生時,替換算法 刪除預先存在-行,也引起在插入或更新當前行之前約束衝突 以及命令 繼續正常執行。如果發生NOT NULL約束衝突 ,REPLACE衝突解決方法會將NULL值替換爲該列的默認值,或者如果該列沒有默認值 ,則使用ABORT算法。如果發生CHECK約束 衝突,則REPLACE衝突解決算法總是 的工作方式與ABORT類似。

我推測您要製作的列UNIQUErollno。您可以通過將其設置爲表格的PRIMARY KEY或通過簡單地在其上創建UNIQUE constrain來使其變得獨特。