2011-12-14 71 views
1

有一個奇怪的問題。我在我的Objective-C的應用程序一個SQLite表:REPLACE INTO sqlite不會取代

NSString *sql = @"CREATE TABLE IF NOT EXISTS user_results (id INTEGER PRIMARY KEY ASC AUTOINCREMENT, gameID INTEGER UNIQUE, gameDesc TEXT, result INTEGER)"; 

然後我執行查詢:

[[DatabaseController getInstance].resultsDB executeUpdate:@"REPLACE INTO user_results (gameID, gameDesc, result) VALUES (?, ?, ?)",[NSNumber numberWithInt:self.gameID],[test JSONRepresentation],[NSNumber numberWithInt:sumBalls]]; 

但問題是,它不具有相同gameID替換該行,它只是增加一個(即使它是UNIQUE),任何想法爲什麼會發生?

P.S.我正在使用FMDB來處理sqlite。

在此先感謝。

解決方案:發送到sql查詢時必須使用[NSNumber numberWithInt:self.gameID].integerValue而不是。

回答

0

gameID字段不是PRIMARY KEY,ID是。如您所見,REPLACE INTO只能與ID字段一起使用。我建議將gameID字段作爲主鍵,以獲得您正在查找的結果。

NSString *sql = @"CREATE TABLE IF NOT EXISTS user_results (gameID INTEGER PRIMARY KEY, gameDesc TEXT, result INTEGER)"; 
+0

不可以,gameID已經是UNIQUE列了,所以REPLACE INTO應該可以正常工作並刪除任何可能使其不唯一的行。 – 2011-12-14 02:42:00

+0

的確如此。 UNIQUE列不應該被覆蓋,所以應該調用REPLACE而不是INSERT。 – 2011-12-14 02:59:23

2

您的模式是否更改,以後添加UNIQUE約束?您的模式& SQL應該按預期工作。我只是想這和它工作得很好:

sqlite3 
CREATE TABLE IF NOT EXISTS user_results (id INTEGER PRIMARY KEY ASC AUTOINCREMENT, gameID INTEGER UNIQUE, gameDesc TEXT, result INTEGER); 
insert into user_results values (1,1,'hi', 1); --insert 2 test rows 
insert into user_results values (2,2,'2', 2); 
select * from user_results; 

1|1|hi|1 
2|2|2|2 

現在插入失敗:

insert into user_results values (3,1,'1', 1); 
Error: column gameID is not unique 

REPLACE INTO做你所期望的:

replace into user_results (gameid, result) values (2, 3); 
select * from user_results; 
1|1|hi|1 
3|2||3 

它刪除的行id爲2,並用新的第3行和第2行替換它。除非您期待它取代主鍵= 2行? Sqlite所做的是刪除任何可能導致違反唯一鍵的行,然後插入新行。請參閱http://www.sqlite.org/lang_conflict.html。請注意,它沒有添加EXTRA行。它刪除了一個,並添加了一個(換句話說,'替換':) :)

如果你的替換到SQL包括ID列,這將工作,在這裏我有效地更新與ID 3行。當然, d必須找出您想要替換的行的編號...

replace into user_results values (3,3,'2', 2); 
select * from user_results; 
1|1|hi|1 
3|3|2|2 

id列是您真正關心的嗎?無論如何,Sqlite會爲你創建一個這樣的列。