我正在研究与c ++数据库相关的项目。我的数据库有几个表,我的项目中每个表都有一个插入函数。我也有一个executeQuery函数。
需要发生的是为表格生成数据。这是订单:
这应该如何运作:
问题:
成功生成其他表后无法生成Subscriber表。
generateSubscriber 功能:
void ConfigStorage::generateSubscriber(CSubscriberResult* res)
{
#if DEF_PROC_TIME_CHECK
time_t start, end;
start = clock();
#endif
CSubscriberResult ret;
SUBSYSTEM_TABLE_COLS* subsystemstable;
int subsystemtable_rows;
selectSubsystemTable(&ret, subsystemtable_rows, subsystemstable); //checked the select results: they are ok
if (ret.res.r != 0)
{
if (res)
{
res->res.s.err = DB_GEN_ERROR;
res->res.s.code = ret.res.s.err;
}
delete [] subsystemstable;
return;
}
SUBSCRIBER* subscriber_insert_data;
int subscriber_insert_count = 0;
int subscriber_types_count = sizeof(subscriber_gen_data) / sizeof(subscriber_gen_data[0]);
for (int i = 0; i < subsystemtable_rows; i++)
{
for (int j = 0; j < subscriber_types_count; j++)
{
if (subsystemstable[i].subsystem == subscriber_gen_data[j].subsystem)
{
if (subscriber_gen_data[j].subscribers_per_subsystem == -1)
{
subscriber_insert_count += SUBSCRIBERS_PER_DC;
}
else
{
subscriber_insert_count += subscriber_gen_data[j].subscribers_per_subsystem;
}
}
}
}
subscriber_insert_data = new SUBSCRIBER[subscriber_insert_count];
int current = 0;
for (int i = 0; i < subsystemtable_rows; i++)
{
for (int j = 0; j < subscriber_types_count; j++)
{
if (subsystemstable[i].subsystem == subscriber_gen_data[j].subsystem)
{
int subscriber_count;
if (subscriber_gen_data[j].subscribers_per_subsystem == -1)
{
subscriber_count = SUBSCRIBERS_PER_DC;
}
else
{
subscriber_count = subscriber_gen_data[j].subscribers_per_subsystem;
}
int subscriber_num = 1;
for (int k = 0; k < subscriber_count; k++)
{
subscriber_insert_data[current].subsystem = subsystemstable[i].id_subsystemtable;
subscriber_insert_data[current].nubmer = randNumber();
subscriber_insert_data[current].name = subsystemstable[i].name + " | Subscriber " + itos(subscriber_num++);
current++;
}
}
}
}
insertSubscriber(&ret, current, subscriber_insert_data);
delete [] subscriber_insert_data;
delete [] subsystemstable;
if (ret.res.r != 0)
{
if (res)
{
res->res.s.err = DB_GEN_ERROR;
res->res.s.code = ret.res.s.err;
}
return;
}
#if DEF_PROC_TIME_CHECK
end = clock();
if (res) res->SetExecTime((end - start) * 1000000 / CLOCKS_PER_SEC);
#endif
}
调用此函数后, subscriber_insert_data 结构已准备好并传递给 insertSubscriber 。
insertSubscriber 功能:
void ConfigStorage::insertSubscriber(CSubscriberResult* res, int count, SUBSCRIBER* pData)
{
#if DEF_PROC_TIME_CHECK
time_t start, end;
start = clock();
#endif
int r;
if ((r = executeQuery("begin transaction", NULL, NULL)) != SQLITE_OK)
{
if (res)
{
res->res.s.err = BEGIN_TRANSACTION_ERROR;
res->res.s.code = r;
}
return;
}
for (int i = 0; i < count; i++)
{
string queryStr = string("insert into subscriber(subsystem, number, name) values(") +
itos(pData[i].subsystem) + string(", \'") + pData[i].nubmer + string("\', \'") + pData[i].name + string("\')");
if ((r = executeQuery(queryStr.c_str(), NULL, NULL)) == SQLITE_OK)
{
if (res)
{
res->res.s.err = OK;
res->res.s.code = r;
}
}
else
{
if (res)
{
res->res.s.err = QUERY_EXECUTION_ERROR;
res->res.s.code = r;
}
executeQuery("rollback", NULL, NULL);
return;
}
}
if ((r = executeQuery("end transaction", NULL, NULL)) != SQLITE_OK)
{
if (res)
{
res->res.s.err = END_TRANSACTION_ERROR;
res->res.s.code = r;
}
return;
}
#if DEF_PROC_TIME_CHECK
end = clock();
if (res) res->SetExecTime((end - start) * 1000000 / CLOCKS_PER_SEC);
#endif
}
此处为每个 subscriber_insert_data 准备 queryStr 并传递给 executeQuery 函数。
executeQuery 功能:
int ConfigStorage::executeQuery(const char* queryStr, int *rows, DATA_STRUCT* data)
{
sqlite3_stmt *statement;
int exec_result;
exec_result = sqlite3_prepare_v2(db, queryStr, -1, &statement, 0); //this is where the error originally occurs
if (exec_result == SQLITE_OK)
{
int cols = sqlite3_column_count(statement);
int result = 0;
while (true)
{
result = sqlite3_step(statement);
if(result == SQLITE_ROW && rows && data)
{
for(int col = 0; col < cols; col++)
{
data[*rows].data[col] = (char*)sqlite3_column_text(statement, col);
}
(*rows)++;
}
else
break;
}
sqlite3_finalize(statement);
}
return exec_result;
}
第一次尝试执行Subscriber表查询时,executeQuery 返回1(这是 sqlite3_prepare_v2 的结果)。
我尝试使用Sqliteman手动执行查询,但它运行正常。
P.S。每次启动程序时,都会使用 sqlite3_open 覆盖并打开数据库文件。