Почему удаление sqlite всегда успешно, даже если строка для удаления не существует? - PullRequest
0 голосов
/ 29 марта 2019

После того, как я создаю таблицу, вставляю в нее данные, а затем удаляю несуществующую строку, операция завершается успешно, даже если строка не существует.Когда я удаляю строку, которая действительно существует, она также успешно выполняется, и строка фактически удаляется.Почему не возникает ошибка, когда я пытаюсь удалить несуществующую строку?

Я использую sqlite3 с c ++ при затмении.Я работал с некоторым кодом, найденным в Интернете, а также со своим собственным.Другие операции, такие как SELECT и INSERT, работают нормально.DELETE работает, когда строки существуют и даже когда они не существуют.

// Создание таблицы

sql = "CREATE TABLE COMPANY("  \
"ID INT PRIMARY KEY     NOT NULL," \
"NAME           TEXT    NOT NULL," \
"AGE            INT     NOT NULL," \
"ADDRESS        CHAR(50)," \
"SALARY         REAL );";

// Вставка данных

sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " \   
"VALUES (1, 'Paul', 32, 'California', 20000.00 ); " \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) "  \
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 ); "     \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );" \
"INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY)" \
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";

// Удаление(это - то, где удаление должно завершиться неудачей, потому что нет идентификатора 30)

rc = sqlite3_open("test.db", &db);

if( rc ) {
    cout << "ERROR ----> " << zErrMsg << endl;
  return(0);
} else {
    fprintf(stderr, "Opened database successfully\n");
}

/* Create SQL statement */
sql = "DELETE FROM COMPANY WHERE ID = 30";

/* Execute SQL statement */
rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);

if( rc != SQLITE_OK ) {
    cout << "ERROR DELETING" << endl;
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
} else {
    fprintf(stdout, "Deletion operation done successfully\n");
}
sqlite3_close(db);

Я ожидаю, что будет отображено сообщение «ОШИБКА УДАЛЕНИЯ», но всегда отображается «Операция удаления выполнена успешно», даже когда идентификаторудалено не существует.

Ответы [ 3 ]

3 голосов
/ 29 марта 2019

Почему не возникает ошибка, когда я пытаюсь удалить несуществующую строку?

Базы данных возвращают количество затронутых строк (удалено в вашем случае), они невыдает ошибку, если с запросом что-то не так.

0 голосов
/ 29 марта 2019

Единственный гарантированный метод проверки удаления строки - выполнение оператора SELECT с такими же условиями.Важным фактором здесь является управление транзакциями, то есть что произойдет, если что-то вызовет откат?Вы явно фиксируете транзакции или разрешаете им автоматическую фиксацию?Вы не должны просто полагаться на коды возврата для этого.Если вы также выполните COUNT, то вы наверняка будете знать, по крайней мере, в течение сеанса:

SELECT COUNT(*) FROM COMPANY WHERE ID = 30

Если после DELETE, COUNT будет 0, строкабольше не существует.

Примечание : этот подход будет полезен, если вам нужен параллелизм, который заставит вас использовать другой механизм базы данных (например, PostgreSQL).

0 голосов
/ 29 марта 2019

Полагаю, что ответ «это по замыслу».

Если вам нужно знать, было ли на последнем операторе DELETE (или, соответственно, INSERT или UPDATE) влияние на ноль (или более) строк (тогда INSERT или UPDATE)вы могли бы использовать:

int sqlite3_changes(sqlite3*);

Это позволит вам реагировать соответствующим образом, если не было удалено ни одной строки.

См. https://www.sqlite.org/c3ref/changes.html

...