语言:c++,数据库:SQLite,问题:怎么把json格式的数据存进去。


node表是:(ID string,NODE string)

自己的处理:利用jsoncpp,做了一个插入函数


 bool ObjManagement::AddJson(string JsonStr)
{
    Json::Reader reader;
    Json::Value json_object;
    reader.parse(JsonStr, json_object, false);
    string jsonID = json_object["ID"].toStyledString();
    cout <<"解析到的jsonID:"<< jsonID << endl;
    string jsonobj = json_object["AVP_LIST"].toStyledString();
    string sqlInsert = "insert into  node values(" + jsonID + ",\"" + jsonobj.c_str() +"\");";
    cout << "拼接成的sqlInsert:" << sqlInsert << endl;
    sqlite3_exec(pdb, sqlInsert.c_str(), 0, 0, &errMsg);
    if (errMsg)
    {
        cout << "ObjManagement: \t sqlInsert:\t" << errMsg << endl;
        return false;
    }
    return true;
}

main函数如下


 int main()
{
    DataBaseManagement *dbm = new DataBaseManagement();
    ObjManagement  *omg = new ObjManagement();
    string strjson = "{\"ID\": \"6851950\", \"AVP_LIST\": [{\"ATTRIBUTE\": \"中文名\", \"VALUE\": \"吴映洁\"}]}";
    cout<<strjson<<endl;
    omg->AddJson(strjson);
    dbm->CloseDb();
    getchar();
}

得到的结果:

图片描述

问题是:怎么能正确插入上述数据

json C++ sqlite

uucomic 11 years, 7 months ago

简而言之就是,你的数据里面带有sql结构的字符,拼接之后改变了sql的结构。

不要手动改单引号,我简单翻了一下api,需要用 sqlite3_mprintf 进行过滤。

小小的乱乱 answered 11 years, 7 months ago

我是这样解决的,我是把json写在一个文本里,,然后读取文本里的json,对它进行操作,没有报错,具体原因,我也不太清楚。主要的原因可能是我一开始那个json格式写的不规范,有错误吧。也特别感谢 @Windoze ,sql确实要注意用单引号的问题,我程序的其他模块有的地方就是没写成单引号而出错。


 f.open("E:\\test.txt");
if (!f)
    cout << "error";
//解析Json的方法
Json::Reader reader;
Json::Value json_object;
reader.parse(f, json_object, false);
f.close();

test.txt里的内容:


 {"ID": "394557", "AVP_LIST": [{"ATTRIBUTE": "topic_equivalent_webpage", "VALUE": "http://baike.baidu.com/view/20338.htm"}, {"ATTRIBUTE": "name", "VALUE": "西汉"}, {"ATTRIBUTE": "entity_pv", "VALUE": "672"}, {"ATTRIBUTE": "entity_category", "VALUE": "年代,朝代"}, {"ATTRIBUTE": "国家领袖", "VALUE": "刘邦、刘彻、刘询"}, {"ATTRIBUTE": "主要民族", "VALUE": "汉族、匈奴、南越族"}, {"ATTRIBUTE": "政治体制", "VALUE": "君主专制政体"}, {"ATTRIBUTE": "货币", "VALUE": "汉五铢"}, {"ATTRIBUTE": "主要民族", "VALUE": "南越族"}, {"ATTRIBUTE": "国家领袖", "VALUE": "刘询"}, {"ATTRIBUTE": "文学体裁", "VALUE": "汉赋"}, {"ATTRIBUTE": "首都", "VALUE": "长安(今西安)"}, {"ATTRIBUTE": "简称", "VALUE": "汉"}, {"ATTRIBUTE": "国家领袖", "VALUE": "刘彻"}, {"ATTRIBUTE": "主要民族", "VALUE": "汉族"}, {"ATTRIBUTE": "主要宗教", "VALUE": "道教"}, {"ATTRIBUTE": "主要城市", "VALUE": "长安、宛、临淄、洛阳、邯郸"}, {"ATTRIBUTE": "主要城市", "VALUE": "长安"}, {"ATTRIBUTE": "所属洲", "VALUE": "亚洲"}, {"ATTRIBUTE": "时区", "VALUE": "东八区"}, {"ATTRIBUTE": "主要城市", "VALUE": "邯郸"}, {"ATTRIBUTE": "国家领袖", "VALUE": "刘邦"}, {"ATTRIBUTE": "国土面积", "VALUE": "1400/1040/2560万(说法不一)"}, {"ATTRIBUTE": "主要民族", "VALUE": "匈奴"}, {"ATTRIBUTE": "主要城市", "VALUE": "洛阳"}, {"ATTRIBUTE": "人口数量", "VALUE": "约6000万(公元2年)"}, {"ATTRIBUTE": "英文名称", "VALUE": "TheHanDynasty"}, {"ATTRIBUTE": "主要城市", "VALUE": "临淄"}, {"ATTRIBUTE": "中文名称", "VALUE": "西汉"}, {"ATTRIBUTE": "官方语言", "VALUE": "中原官话"}, {"ATTRIBUTE": "主要城市", "VALUE": "宛"}]}

zscbc answered 11 years, 7 months ago

  1. SQL里的字符串要用单引号
  2. 你需要escape,也就是说,JSON里如果出现了单引号,你要把它变成两个单引号

 template<typename Input, typename Output>
inline void SQL_escape(Input in, Output &out) {
    if(*in=='\'') *out++='\'';
    *out++=*in;
}

template<typename Input, typename Output>
inline void SQL_escape(Input start, Input stop, Output out)
{ for(Input i=start; i!=stop; ++i) SQL_escape(i, out); }

然后你就可以这么用:


 std::string s="A JSON string with single quote(') inside";
    std::string escaped;
    SQL_escape(s.begin(), s.end(), std::back_inserter(escaped));
    std::cout << "INSERT INTO node VALUES('"<< escaped << "')" << std::endl;

飞机是这样的 answered 11 years, 7 months ago

Your Answer