You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt环境下SQLite3+Spatialite执行INSERT查询随机出现语法错误

问题根本原因
  • 野指针访问内存:你代码中获取SQL字符串C风格指针的逻辑存在严重错误:
    行char *query = strQuery.toLatin1().data();中,strQuery.toLatin1()返回的是临时QByteArray对象,该对象在当前语句执行完成后就会被自动析构,其内部存储的字符串内存也会被释放。后续sqlite3_prepare_v2调用读取query指向的已经被释放的内存时,内容是随机的:如果内存还未被其他数据覆写,SQL执行正常;如果已经被覆写为垃圾数据,就会出现你遇到的随机语法错误(比如报错里的乱码、随机关键字报错)。
  • 你将生成的SQL复制到SpatialiteGUI中运行始终正常,是因为复制的是未被破坏的正确SQL字符串,不存在内存损坏问题。
修复方案

快速修复(直接解决野指针问题)

将SQL字符串转C指针的逻辑修改为保留临时字节数组对象,避免提前析构即可:

bool DatabaseManager::insertPolygons(QList<QList<QGeoCoordinate>> polygons, int workId) 
{
    sqlite3_stmt *dbStatement = nullptr;
    QString strQuery = "INSERT INTO \"WORK_" + QString::number(workId) + "\" (Geometry) VALUES ";
    bool inserted = false;
    for(int i = 0; i < polygons.size(); i++) {
        strQuery += "(GeomFromText('POLYGON((";
        foreach (QGeoCoordinate coordinate, polygons[i]) {
            strQuery += QString::number(coordinate.longitude(), 'f', 10) + " " +
                        QString::number(coordinate.latitude(), 'f', 10)  + ",";
        }
        strQuery = strQuery.left(strQuery.size() - 1) + "))', 4326)),";
    }
    strQuery = strQuery.left(strQuery.size() - 1) + ";";
    // 修改开始:保留字节数组对象避免提前释放,用Utf8兼容更多场景
    QByteArray queryByteArray = strQuery.toUtf8();
    const char* query = queryByteArray.constData();
    int status = sqlite3_prepare_v2(database, query, queryByteArray.size(), &dbStatement, 0);
    // 修改结束
    if(status == SQLITE_OK) {
        int stepStatus = sqlite3_step(dbStatement);
        if(stepStatus == SQLITE_DONE)
            inserted = true;
    }else
        qDebug().noquote() << "status:" << status << "error:" << sqlite3_errmsg(database);
    sqlite3_finalize(dbStatement);
    return inserted; 
}

修改后queryByteArray是当前函数的局部变量,直到函数执行完成才会销毁,query指针全程指向有效内存,不会再出现随机内容损坏问题。

优化方案(更安全高效)

你当前直接拼接SQL字符串的方式存在SQL注入风险,且批量插入效率较低,建议改用SQLite预编译参数绑定逻辑实现:

  1. 预编译固定模板的插入语句:INSERT INTO "WORK_xxx" (Geometry) VALUES (GeomFromText(?, 4326))
  2. 循环绑定每个多边形的WKT字符串参数,执行step后重置语句,批量插入性能更高也更安全。

内容的提问来源于stack exchange,提问作者JonatasCV

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 16:45:02