2011-12-14 2 views
1

получил странную проблему. У меня есть SQLite таблицу в моей Objective-C приложения: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.

Заранее спасибо.

Решение: бы использовать [NSNumber numberWithInt:self.gameID].integerValue вместо при отправке запросов SQL.

ответ

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 должен отлично работать и удалять любые строки, которые сделают его не уникальным. –

+0

Это правда. Столбец UNIQUE не должен быть перезаписан, поэтому вместо INSERT следует вызывать REPLACE. –

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 

Он удалил строку с идентификатором 2, и заменил его новой строкой id 3 и gameid 2. Если вы не ожидали, что он заменит первичный ключ = 2 строки? Что Sqlite делает, удаляет любые предыдущие строки, которые могут вызвать нарушение уникального ключа, а затем вставляет новую строку. См. http://www.sqlite.org/lang_conflict.html. Заметьте, что он не добавил строку EXTRA. Он удалил один и добавил один (другими словами, «заменил» :)

Если ваша замена на SQL включала в себя столбец идентификатора, это могло бы работать, здесь я эффективно обновляю строку с идентификатором 3. Конечно, d необходимо выяснить идентификатор строки, которую вы хотели бы заменить ...

Столбец id что-то действительно вас беспокоит? Sqlite создаст для вас такую ​​колонку.

+0

Я действительно нашел проблему. Поскольку я отправлял executeUpdate [номер NSNumberWithInt: sumBalls], он отправлял не фактическое значение sumBalls. '[Номер NSNumberWithInt: self.gameID] .integerValue' сделал трюк. Благодарю. –

Смежные вопросы