2011-12-14 58 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会为你创建一个这样的列。