Когда происходит нарушение ограничения UNIQUE, алгоритм REPLACE удаляет ранее существовавшие строки, вызывающие нарушение ограничения, перед вставкой или обновлением текущей строки, и команда продолжает выполняться в обычном режиме. Это приводит к изменению rowid и создает следующую проблему
Y:> **sqlite3 test**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **create table b (c1 integer primary key, c2 text UNIQUE);**
sqlite> **insert or replace into b values (null,'test-1');**
sqlite> **select last_insert_rowid();**
1
sqlite> **insert or replace into b values (null,'test-2');**
sqlite> **select last_insert_rowid();**
2
sqlite> **insert or replace into b values (null,'test-1');**
sqlite> **select last_insert_rowid();**
3
sqlite> **select * from b;**
2|test-2
3|test-1
Обходной путь заключается в изменении определения столбца c2 следующим образом.
create table b (c1 integer primary key, c2 text UNIQUE ON CONFLICT IGNORE);
и удалить предложение «или заменить» из ваших вставок;
затем при тестировании после вставки вам нужно будет выполнить следующий sql: select last_insert_rowid(), changes();
sqlite> **create table b (c1 integer primary key, c2 text UNIQUE ON CONFLICT IGNORE);**
sqlite> **insert into b values (null,'test-1');**
sqlite> **select last_insert_rowid(), changes();**
1|1
sqlite> **insert into b values (null,'test-2');**
sqlite> **select last_insert_rowid(), changes();**
2|1
sqlite> **insert into b values (null,'test-1');**
sqlite> **select last_insert_rowid(), changes();**
2|0
Возвращаемое значение изменений после 3-й вставки будет уведомлением для вашего приложения о том, что вам нужно будет найти идентификатор строки «test-1», поскольку он уже был в файле. Конечно, если это многопользовательская система, вам также нужно будет обернуть все это в транзакцию.
person
Noah
schedule
27.01.2011