最近使用sqlite3_bind_*()函数时遇到一个问题,插入的数据是乱码,并且英文,中文都是乱码,并且插入的数据都是一样的乱码,除了字符串,其他类型的数据是正常的,代码如下:
....
sqlite3_stmt *stmt;
unsigned int rec_offset = 0;
if (sqlite3_prepare_v2 (dbHandle, cmdString, strlen(cmdString), &stmt, NULL) == SQLITE_OK)
{
for (unsigned int i = 0; i < row_num; ++i)
{
for (unsigned int k = 0; k < columnVector.size(); k++)
{
switch (columnVector[k].type)
{
case DB_DATATYPE_STRING :
{
char * tmp_char = (char*)malloc (columnVector[k].data_size);
memcpy (tmp_char, (char*)data_buffer + rec_offset, columnVector[k].data_size);
sqlite3_bind_text (stmt, k + 1, tmp_char, columnVector[k].data_size, SQLITE_STATIC);
free (tmp_char);
break;
}
case DB_DATATYPE_INT:
{
int tempInt;
memcpy (&tempInt, (char*)data_buffer + rec_offset, sizeof(int));
sqlite3_bind_int(stmt, k + 1, tempInt);
break;
}
...
default:
{
cout<<"不支持的数据类型!!!!!"<<endl;
break;
}
}//switch 一行的每一列按类型进行绑定处理
rec_offset += columnVector[k].data_size;
}//for(k) 一行的所有列处理完毕
int retcode = sqlite3_step (stmt);
if ( retcode == SQLITE_DONE)
{
sqlite3_reset (stmt);
}
}//for(i) 所有数据绑定完毕
int retcode = sqlite3_finalize (stmt);
...
}
经过上网查找问题,找到一篇帖子(https://www.jb51.net/article/110054.htm)感觉跟我的情况有点像,经过修改部分代码解决了该问题,原因是在sqlite3_step (stmt)之前,调用bind绑定的一行数据必须仍然存在,不能被释放,否则就不能真正写入。
修改代码如下:
....
if (sqlite3_prepare_v2 (dbHandle, cmdString, strlen(cmdString), &stmt, NULL) == SQLITE_OK)
{
for (unsigned int i = 0; i < row_num; ++i)
{
//申请最大内存,这里假设字符串类型字段长度不超过500,每个字段都是字符串类型
char *tmp_char = (char*)calloc(500 * columnVector.size(), 1);
for (unsigned int k = 0; k < columnVector.size(); k++)
{
switch (columnVector[k].type)
{
case DB_DATATYPE_STRING :
{
memcpy (tmp_char + 500 * k, (char*)data_buffer + rec_offset, columnVector[k].data_size);
sqlite3_bind_text (stmt, k + 1, tmp_char + 500 * k, columnVector[k].data_size, SQLITE_STATIC);
break;
}
...
}//switch 一行的每一列按类型进行绑定处理
rec_offset += columnVector[k].data_size;
}//for(k) 一行的所有列处理完毕
int retcode = sqlite3_step (stmt);
free(tmp_char); //释放申请的内存
if ( retcode == SQLITE_DONE)
{
sqlite3_reset (stmt);
}
}//for(i) 所有数据绑定完毕
int retcode = sqlite3_finalize (stmt);
...
}
记录下这个问题,希望能帮助解决出现同样问题的朋友。