SQLite3的绑定函数族使用时需要注意的一个问题

最近使用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);
    ...
}

​

​

记录下这个问题,希望能帮助解决出现同样问题的朋友。

发布了65 篇原创文章 · 获赞 34 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/huanggang982/article/details/98167786