2015-04-11 7 views
0

Я пытаюсь увеличить количество строк в базе данных SQLite, если строка существует, или добавить новую строку, если она не существует, как это делается в этом сообщении SO. Однако я получаю какое-то странное поведение, когда я пытаюсь выполнить этот процесс SQL много раз подряд. В качестве примера я попытался запустить этот код:Странное поведение при вставке или замене SQLite

db = connect_to_db() 
c = db.cursor() 
for i in range(10): 
    c.execute("INSERT OR REPLACE INTO subject_words (subject, word, count) VALUES ('subject', 'word', COALESCE((SELECT count + 1 FROM subject_words WHERE subject = 'subject' AND word = 'word'), 1));") 
    db.commit() 
db.close() 

И вставить следующий текст в базу данных

sqlite> select * from subject_words; 
subject|word|1 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 
subject|word|2 

, который насчитывает до 19 записей слова «слова» с темой «предметом». Может ли кто-нибудь объяснить это странное поведение?

+0

Нет, это 10 записей, по одному на каждую итерацию вашего цикла. Что вы ожидали? –

+0

Я ожидаю одну запись с третьим значением 10 – azrosen92

+0

Есть ли у вас какие-либо ограничения, которые были бы нарушены этой вставкой, чтобы было вызвано предложение replace? –

ответ

1

Я не думаю, что вы поняли, что на самом деле делает INSERT OR REPLACE. Предложение REPLACE будет вступать в игру только в том случае, если было невозможно выполнить вставку, поскольку было нарушено уникальное ограничение. Например, если ваш основной столбец subject.

Однако, без каких-либо первичных ключей или других ограничений, нет ничего, что может быть нарушено путем вставки нескольких строк с одним и тем же предметом; поэтому нет причин ссылаться на предложение REPLACE.

1

Эта операция намного проще писать и понимать, если вы делаете это с двумя SQL заявления:

c.execute("""UPDATE subject_words SET count = count + 1 
      WHERE subject = ? AND WORD = ?""", 
      ['subject', 'word']) 
if c.rowcount == 0: 
    c.execute("INSERT INTO subject_words (subject, word, count) VALUES (?,?,?)", 
       ['subject', 'word', 1]) 

Это не требует уникального ограничения на колонки, которые вы хотите проверить, и не какой-либо менее эффективным ,

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