为什么即使删除的行不存在,sqlite的删除也总是成功?

时间:2019-03-29 02:58:18

标签: c++ sql sqlite sql-delete

创建表后,将数据插入表中,然后删除不存在的行,即使该行不存在,操作也会成功。当我删除实际存在的行时,它也会成功执行,并且该行实际上也会被删除。当我尝试删除不存在的行时为什么没有出现错误?

我在eclipse上使用带c ++的sqlite3。 我一直在使用网络上以及我自己的代码。 其他操作(例如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 );";

//删除(这是删除失败的原因,因为没有  ID 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);

我希望显示消息“错误删除”,但即使不存在删除的ID,也总是显示“删除操作成功完成”。

3 个答案:

答案 0 :(得分:3)

当我尝试删除不存在的行时为什么不会出现错误?

数据库返回受影响的行数(在您的情况下已删除),除非查询有问题,否则它们不会引发错误。

答案 1 :(得分:0)

我猜答案是“这是设计使然”。

如果您需要知道零(或更多)行是否受到最后一个DELETE语句(或与此有关的INSERT或UPDATE)的影响,则可以考虑使用:

int sqlite3_changes(sqlite3*);

如果未删除任何行,这将使您做出相应的反应。

请参见https://www.sqlite.org/c3ref/changes.html

答案 2 :(得分:0)

检查行是否已删除的唯一保证方法是在相同条件下执行SELECT语句。交易控制在这里是一个重要因素,即,如果某件事导致回滚会发生什么?您是在明确地提交事务,还是允许它们自动提交?您不应该仅仅依赖于返回码。如果您也执行COUNT,则至少在会话期间,您将肯定知道:

SELECT COUNT(*) FROM COMPANY WHERE ID = 30

如果在DELETE之后,COUNT0,则该行不再存在。

注意:如果需要并发,这种方法将很有用,这将迫使您使用其他数据库引擎(例如PostgreSQL)。