c++ - c++ sqlite3更新查询未提交
问题描述
我正在学习如何为 c++ 使用 sqlite3 库,到目前为止,我设法执行 SELECT 查询并创建新表,但似乎更新/插入不起作用:
作为模拟测试,我使用的是静态查询(不使用变量):
int rc {0};
char *zErrMsg {0};
sql = "UPDATE tag_list set name = 'foo' where ID=16; " \
"SELECT * from tag_list";
rc = sqlite3_exec(this->db_ptr, sql, callback, (void*)data, &zErrMsg);
if( rc != SQLITE_OK ) {
fprintf(stderr, "SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
fprintf(stdout, "Operation done successfully\n");
}
我的回调函数是:
static int callback(void *data, int argc, char **argv, char **azColName){
int i;
fprintf(stderr, "%s: ", (const char*)data);
for(i = 0; i<argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
printf("\n");
return 0;
}
输出:
id = 14
name = computer
last_update = 123
id = 16
name = foo
last_update = 1
Operation done successfully
当我直接查询数据库时,这就是我得到的:
╔════╦══════════╦═════════════╗
║ ID ║ name ║ Last_update ║
╠════╬══════════╬═════════════╣
║ 14 ║ computer ║ 123 ║
║ 16 ║ s ║ 1 ║
╚════╩══════════╩═════════════╝
我使用 sqlite3_get_autocommit 检查并返回 1,据我了解,这意味着它是自动提交的。
我可以从外部更新行,它只发生在代码中。
tl; dr:我正在尝试更新我创建的表中的名称,但似乎没有提交更改。
我希望有更多经验的人以前遇到过这个并且知道如何绕过这个。
解决方案
所以我设法找到了我的问题,它根本不在发布的代码中..
我的问题是我将我的 sqlite3 指针传递给另一个类,认为它是通过引用而不是副本。
上面的代码形式来自我的另一个类,我可以在其中查询数据,但不能写入/更改。
如 SQLite3 文档 ( https://www.sqlite.org/lockingv3.html ) 中所述:
一次只有一个进程可以持有 RESERVED 锁。但是其他进程可以在保留保留锁被持有时继续读取数据库。
代码:
主.cpp:
in main() {
sqlite3 *db_ptr;
sqlite3_open("test.db",db_ptr);
ConfigurationManager *config_manager = new ConfigurationManager(db_ptr);
}
配置管理器.cpp:
ConfigurationManager::ConfigurationManager(sqlite3 *db) {
std::cout << "in constructor" << std::endl;
this->db_ptr = db;
if (initialize_db()) { // initialize_db() creates tables if they don't exist
std::cout << "Configuration table initialized" << std::endl;
}
}
int ConfigurationManager::update_rule_last_run(int id) {
int rc {0};
char *zErrMsg = 0;
auto epoch = std::chrono::system_clock::now().time_since_epoch();
auto epoch_seconds = std::chrono::duration_cast<std::chrono::seconds>(epoch).count();
std::ostringstream string_stream;
string_stream << "Update discovery_rules ";
string_stream << "SET last_run = " << epoch_seconds <<" ";
string_stream << "Where id = " << id << ";";
std::string query = string_stream.str();
std::cout << "- Rule Id " << id << " update command: " << query << std::endl;
rc = sqlite3_exec(this->db_ptr, query.c_str(), NULL,NULL, &zErrMsg);
if (rc != SQLITE_OK) {
std::cout << "Error occured while polling discovery rules: " << zErrMsg << std::endl;
throw std::exception();
}
return 0;
}
一个可能的解决方案(我发现的一个)是为 sqlite3 创建一个包装类并管理来自它的所有查询。
推荐阅读
- python - 来自kafka的json无法转换为pandas
- java - 如何比较java中的字符串/字符,如果不相等,如何在字符串之间放置符号?
- android - 将特定内容添加到空的 LinearLayout 中导致错误
- kotlin - HashMap 通过 Key 获取值
- flutter - 更新 Xcode 后出现此条纹问题 ^
- ruby-on-rails - 为方法内部的方法编写 rspec
- java - Java Spring POST 与数组和对象 JSON 数据问题
- flutter - 即使 Wifi 在 Flutter 中关闭,互联网地址查找也显示已连接
- eclipse - 使用相对 Eclipse 小写“系统”变量路径时,如何“向上”一个文件夹(转到父文件夹)?
- mysql - 是否有触发器可以帮助我从日常记录表中更新报告表?我