C++中SQLite外键约束违规排查:删除行回调未触发问题
外键约束问题排查:DELETE操作触发SQLITE_CONSTRAINT_FOREIGNKEY但PRAGMA foreign_key_check无输出?
我正在为程序添加删除数据库任意行的功能,目标数据库与另外6个数据库共享外键。我已通过以下代码确保开启外键支持:
void SQLitePatternSet::enableForeignKeys() { char *msg; int result = sqlite3_exec(db1, "PRAGMA foreign_keys=ON;", nullptr, nullptr, &msg); if(result != SQLITE_OK) { std::string errMsg = "Failed to enable foreign key support: "; errMsg += msg; sqlite3_free(msg); throw std::runtime_error(errMsg); } }
同时已为数据库对应行配置了ON DELETE CASCADE规则,但执行删除操作时仍收到SQLITE_CONSTRAINT_FOREIGNKEY错误。为了定位违规的外键,我在removeRow函数中添加了相关检查逻辑:
bool SQLitePatternSet::removeRow(const std::int64_t db1RowID) { bool removed = true; std::string sql = "DELETE FROM Database1 WHERE RowID = :id;"; sqlite3_stmt *removeStmt; prepStatement(sql, removeStmt); sqlite3_bind_int64(removeStmt, 1, db1RowID); int sqlResult = sqlite3_step(removeStmt); if(sqlResult != SQLITE_DONE) { if(sqlite3_extended_errcode(db1) == SQLITE_CONSTRAINT_FOREIGNKEY) { removed = false; result = sqlite3_exec(db1, "PRAGMA foreign_key_check(Database1);", foreignKeyCheckCallback, nullptr, nullptr); } else { auto errMsg = formatErrMsg("removeRow failed"); throw pset_errors::storage_error(errMsg); } } data1.erase(db1RowID); sqlite3_finalize(removeStmt); return removed; }
但实际测试时遇到了问题:我编写的回调函数从未执行,尽管sqlite3_exec返回0(说明语法无错误)。按道理这意味着没有触发外键冲突的键,但实际明明存在冲突。请问这是怎么回事?是foreign_key_check本质不会向回调输出内容吗?
我的回调函数代码如下:
int foreignKeyCheckCallback(void *a_param, int argc, char **argv, char **column){ std::string msg = "Foreign key check:\n"; for (int i = 0; i < argc; i++) { msg += argv[i]; if (i < argc - 1) msg += "\n"; } throw std::runtime_error(msg); return 1; }
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

