我有一个使用SQLite版本3.43.1的c程序(DB浏览器版本3.12.2,其中有SQLite版本3.35.5)。我创建一个表并在该表中插入数据。当我想读取表:SELECT NAME FROM "mytable"
时,我得到一个错误代码1和错误消息no such table: mytable
。
注意事项:我看到很多以前的答案说“你需要指向数据库”。我正在从我写过的同一个数据库中查询,没有错误。我也使用DB浏览器(一旦我的程序断开连接),我使用相同的查询并查看我的数据。
我还在程序中使用了以下查询来查看表列表:SELECT * FROM sqlite_master WHERE name LIKE 'mytable'
。
怎么可能?我不知道该怎么办。
另请注意:我尝试了sqlite_exec和非 Package 的方法(sqlite_v2,step,sqlite3_column_text)。在这一点上,我看不出使用回调或step+column_text之间的变化有什么不同。
数据库的创建是使用常规的sqlite3_open完成的。除了文件路径之外没有其他参数。表的创建使用默认的CREATE TABLE mytable (ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, NAME TEXT NOT NULL, VAL TEXT);
。没有其他参数。
我正在Ubuntu 12.3.0上使用g 12.3.0(通过Windows WSL)编译sqlite3.h和sqlite3.c文件,这些文件是由来自sqlite网站的压缩sqlite-amalgamation-343100提供的。
等效编译命令:gcc -fPIC -lpthread -ldl -lm -c sqlite3.o -o code/sqlite-amalgamation-3430100/sqlite3.c
db.h
#pragma once
// Third-Party
#include <sqlite3.h>
// C++ Standard
#include <filesystem>
#include <iostream>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>
class DB {
public:
void setFilepath(std::filesystem::path);
std::filesystem::path getFilepath();
void connect();
void close();
void write(std::string);
void read(std::string);
private:
sqlite3* db;
std::filesystem::path db_path;
}
字符串
db.cpp
#include "db.h"
static int callback(void* list, int cols, char** dat, char** colname) {
std::cout << "callback called" << std::endl;
for (int i = 0; i < cols; i++) {
printf("%s = %s\n", colname[i], dat[i] ? dat[i] : "NULL");
std::cout << colname[i] << " = " << dat[i] << std::endl;
}
printf("\n");
return 0;
}
void DB::setFilepath(std::filesystem::path fp) {
std::string msg = "DB set filepath " + fp.string();
spdlog::info(msg);
if (fp.extension() != ".db") {
fp.replace_extension(".db");
}
db_path = fp;
return;
}
std::filesystem::path DB::getFilepath() {
return db_path;
}
void DB::connect() {
int ret_code = sqlite3_open(db_path.string().c_str(), &db);
//const char* zVfs = "";
//int ret_code = sqlite3_open_v2(db_path.string().c_str(), &db, 0, zVfs);
if (ret_code) {
std::string msg1 = "DB return code error ";
std::string msg2 = sqlite3_errmsg(db);
spdlog::error(msg1 + msg2);
exit(0);
}
}
void DB::close() {
sqlite3_close(db);
}
void DB::write(std::string query) {
connect();
int ret_code;
char* pzErrMsg = 0;
ret_code = sqlite3_exec(db, sql_str.c_str(), callback, pArg, &pzErrMsg);
if (ret_code != SQLITE_OK) {
spdlog::error("Execution error");
sqlite3_free(pzErrMsg);
}
close();
return;
}
void DB::read(std::string sql_str) {
int ret_code = 0;
sqlite3_stmt* stmt;
char* zErrMsg = 0;
connect();
ret_code = sqlite3_prepare_v2(db, sql_str.c_str(), -1, &stmt, nullptr);
std::cout << "ret code: " << ret_code << std::endl;
// I receive the error HERE
// #########################################################
// exe fail
// no such table: mytable <--------------- HERE
// #########################################################
if (ret_code != SQLITE_OK) {
std::cout << "exec fail" << std::endl;
std::cerr << sqlite3_errmsg(db) << '\n';
sqlite3_free(zErrMsg);
exit(1);
}
do {
ret_code = sqlite3_step(stmt);
// #########################################################
// # PLEASE DO NOT WORRY ABOUT THIS RIGHT NOW #
// # THIS IS NOT WHERE THE ERROR OCCURS #
// #########################################################
std::cout << "ret code loop: " << ret_code << std::endl;
std::cout << sqlite3_column_text(stmt, 0) << ":";
std::cout << sqlite3_column_text(stmt, 1) << std::endl;
} while (ret_code == SQLITE_ROW);
if (ret_code != SQLITE_DONE) { // 101
std::cout << "ret_code not done" << std::endl;
std::cerr << sqlite3_errmsg(db) << '\n';
}
// close
sqlite3_finalize(stmt);
sqlite3_close(db);
}
型
main.cpp
// C Standard
#include <stdlib.h>
#include <stdio.h>
// Custom - Utils
#include "db.h"
// C++ Standard
#include <fstream>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
void createTables(DB proj_db) {
proj_db.write("CREATE TABLE mytable (\"ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, NAME TEXT NOT NULL, VALUE TEXT\");");
proj_db.write("CREATE TABLE myOtherTable (\"ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, NAME TEXT NOT NULL, VALUE TEXT\");");
}
void writeDatafromFile(json file, DB proj_db) {
// read data
...
// write to DB
proj_db.write("INSERT INTO mytable (NAME,VALUE) \"abc\",\"123\"");
}
void readDatabase(DB proj_db) {
proj_db.read("SELECT NAME FROM \"mytable\";"); //fail
proj_db.read("SELECT * FROM sqlite_master WHERE name LIKE \'mytable\';"); // output is empty; doesn't see any tables to list; should at least list my table creations
// write to csv
...
}
int main(int argc, char const* argv[]) {
DB proj_db;
proj_db = DB();
std::filesystem::path db_fp; // obtained from arguments, same directory is fine. ends with .db. example: ./mydatabase.db
proj_db.setFilepath(db_fp);
if (arguments.new()) createTables();
if (arguments.inputFileExists()) writeDatafromFile();
if (arguments.outputFlagExists()) readDatabase();
return 0;
}
型
bash终端:
rm -rf myproject.db # this is to ensure a new sqlite db is created
./myprogram --db myproject --new # I create a blank sql db file called myproject.db; creates empty tables (mytable, myOthertable, etc)
./myprogram --db myproject --in data.json # I write data parsed from a file (equivalent to ~2-3 INSERT mytable sql commands); successful; verified with DB browser after program is closed
./myprogram --db myproject --in data2.json # another set of writes (sometimes to another table); successful; verified with DB Browser
./myprogram --db myproject --out mystuff.csv # queries tables (SELECT NAME from mytable) <------ ERROR HERE, but DB Browser shows data and my schema
型
我的实际程序返回读取命令的值。只是不想让这个最小的程序复杂化。只要我能修复错误代码,我就能处理剩下的。
1条答案
按热度按时间o2gm4chl1#
字符串
对我来说是有效的,所以你的insert和select语句都是错误的。特别是你的DB::read方法试图读取两个列值,所以你需要一个
select
,它至少返回两个文本值。另外,你需要型
在DO循环中
(and在测试前删除现有数据库一次)