Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
仅在Android上查询时发生SQL逻辑错误 我正在研究一个C++ Stand NDK项目,它依赖于一个SqLITE3数据库作为数据仓库。数据库有三个表;列计数为6、8和6;行数分别为240、1250万和400万_Android_C++_Sqlite_Android Ndk - Fatal编程技术网

仅在Android上查询时发生SQL逻辑错误 我正在研究一个C++ Stand NDK项目,它依赖于一个SqLITE3数据库作为数据仓库。数据库有三个表;列计数为6、8和6;行数分别为240、1250万和400万

仅在Android上查询时发生SQL逻辑错误 我正在研究一个C++ Stand NDK项目,它依赖于一个SqLITE3数据库作为数据仓库。数据库有三个表;列计数为6、8和6;行数分别为240、1250万和400万,android,c++,sqlite,android-ndk,Android,C++,Sqlite,Android Ndk,SQLite驱动程序正在编译,未经修改,直接从SQLite3合并源代码3.19.3版编译到我的本机库中 我的问题是,在运行本机库时,数据库查询会导致“SQL逻辑错误或缺少数据库”。我知道数据库在我期望的地方,并且可以访问。如果我在桌面环境(而不是在移动设备上)对同一数据库执行相同的查询,我会看到预期的结果。此外,如果我使用存储库中包含数据子集的数据库(总共约300条记录)在移动设备上执行相同的查询,我会看到预期的结果 有什么想法吗 作为参考,以下是我使用的查询: WITH weathe

SQLite驱动程序正在编译,未经修改,直接从SQLite3合并源代码3.19.3版编译到我的本机库中

我的问题是,在运行本机库时,数据库查询会导致“SQL逻辑错误或缺少数据库”。我知道数据库在我期望的地方,并且可以访问。如果我在桌面环境(而不是在移动设备上)对同一数据库执行相同的查询,我会看到预期的结果。此外,如果我使用存储库中包含数据子集的数据库(总共约300条记录)在移动设备上执行相同的查询,我会看到预期的结果

有什么想法吗

作为参考,以下是我使用的查询:

WITH 
    weather_distance AS 
        (SELECT  latitude, longitude, temperature, humidity, time, (ABS((latitude - $lat)) + ABS((longitude - $lon))) AS distance FROM Weather WHERE time BETWEEN $start AND $end), 
    min_weather_distance AS 
        (SELECT latitude, longitude, temperature, humidity, time FROM weather_distance WHERE distance = (SELECT MIN(distance) FROM weather_distance)), 
    solar_distance AS 
        (SELECT  latitude, longitude, ghi, (time - 1800) AS time, (ABS((latitude - $lat)) + ABS((longitude - $lon))) AS distance FROM SolarData WHERE time BETWEEN $start AND $end), 
    min_solar_distance AS 
        (SELECT  latitude, longitude, ghi, time FROM solar_distance WHERE distance = (SELECT MIN(distance) FROM solar_distance)) 
SELECT s.time, s.ghi, w.temperature, w.humidity FROM min_weather_distance w INNER JOIN min_solar_distance s ON w.time = s.time ORDER BY s.time ASC
以及我用来进行查询的代码(C++):

const char* getEnvQuery =
        "WITH "
            "weather_distance AS "
                "(SELECT  latitude, longitude, temperature, humidity, time, (ABS((latitude - $lat)) + ABS((longitude - $lon))) AS distance FROM Weather WHERE time BETWEEN $start AND $end), "
            "min_weather_distance AS "
                "(SELECT latitude, longitude, temperature, humidity, time FROM weather_distance WHERE distance = (SELECT MIN(distance) FROM weather_distance)), "
            "solar_distance AS "
                "(SELECT  latitude, longitude, ghi, (time - 1800) AS time, (ABS((latitude - $lat)) + ABS((longitude - $lon))) AS distance FROM SolarData WHERE time BETWEEN $start AND $end), "
            "min_solar_distance AS (SELECT  latitude, longitude, ghi, time FROM solar_distance WHERE distance = (SELECT MIN(distance) FROM solar_distance)) "
        "SELECT s.time, s.ghi, w.temperature, w.humidity FROM min_weather_distance w INNER JOIN min_solar_distance s ON w.time = s.time ORDER BY s.time ASC;\0";

sqlite3_stmt* getEnvStmt;
prepareSqlStatement(getEnvQuery, &getEnvStmt, envdbhandle, "Error preparing SQL statement to retrieve environmental data. SQLite return code: ");
sqlite3_bind_double(getEnvStmt, 1, iter->latitude); //iter is defined above quoted code
sqlite3_bind_double(getEnvStmt, 2, iter->longitude);
sqlite3_bind_double(getEnvStmt, 3, iter->startTime);
sqlite3_bind_double(getEnvStmt, 4, iter->endTime);
__android_log_print(ANDROID_LOG_DEBUG, "SPP/getEnvironment", "Bound parameters: lat=%f, lon=%f, start=%ld, end=%ld", iter->latitude, iter->longitude, iter->startTime, iter->endTime);
int rc = sqlite3_step(getEnvStmt);
__android_log_print(ANDROID_LOG_DEBUG, "SPP/getEnvironment", "step(getEnvStmt) = %d", rc);
int errCode = sqlite3_extended_errcode(envdbhandle);
__android_log_print(ANDROID_LOG_DEBUG, "SPP/getEnvironment", "Most recent SQLITE error code: %s. Message: %s", sqlite3_errstr(errCode), sqlite3_errmsg(envdbhandle));
while(rc == SQLITE_ROW)
{
    EnvironmentDatum envData;
    int dbTime = sqlite3_column_int(getEnvStmt, 0);
    envData.UnixTime = timeconvert::secondsOfYearToUNIXTime(dbTime, year);
    __android_log_print(ANDROID_LOG_DEBUG, "SPP/getEnvironment", "EnvironmentDatum dbTime=%d, UnixTime=%f", dbTime, envData.UnixTime);
    envData.GHI = sqlite3_column_double(getEnvStmt, 1);
    envData.Temperature = sqlite3_column_double(getEnvStmt, 2);
    envData.Humidity = sqlite3_column_double(getEnvStmt, 3);
    envCollection.push_back(envData);
    rc = sqlite3_step(getEnvStmt);
}
sqlite3_finalize(getEnvStmt);
重要调试信息:

sqlite3_stmt* verQueryStmt;
prepareSqlStatement("select sqlite_version();\0", &verQueryStmt, envdbhandle, "Error getting driver version. Error code:");
sqlite3_step(verQueryStmt);
std::string sqliteVersion = parseSqliteStringColumn(verQueryStmt, 0);
sqlite3_finalize(verQueryStmt);
__android_log_print(ANDROID_LOG_DEBUG, "SPP/buildScenario", "sqlite version=%s", sqliteVersion.c_str()); // outputs "sqlite version=3.19.3"
__android_log_print(ANDROID_LOG_DEBUG, "SPP/buildScenario", "env db readability=%s", (sqlite3_db_readonly(envdbhandle, "main") == 1 ? "READONLY" : (sqlite3_db_readonly(envdbhandle, "main") == 0 ? "READ/WRITE" : "NOT CONNECTED"))); // outputs "READ/WRITE"
根据请求,以下是准备声明:

static int prepareSqlStatement(const char* query, sqlite3_stmt** statement, sqlite3* db, const char* failMsg)
{
    int returnCode = sqlite3_prepare(db, query, -1, statement, NULL);
    if(returnCode != SQLITE_OK || statement == NULL)
    {
        int errCode = sqlite3_extended_errcode(dbhandle);
        std::cout << "Most recent SQLITE error code: " << sqlite3_errstr(errCode) << ". Message: " << sqlite3_errmsg(dbhandle) << std::endl;
        reportError(failMsg, -1 * returnCode);
    }
    return returnCode;
}
static int prepareSqlStatement(const char*query、sqlite3\u stmt**语句、sqlite3*db、const char*failMsg)
{
int returnCode=sqlite3\u prepare(数据库,查询,-1,语句,NULL);
if(returnCode!=SQLITE_OK | |语句==NULL)
{
int errCode=sqlite3\u extended\u errCode(dbhandle);

当查询的中间结果变得太大时,数据库必须将一些数据交换到一个临时文件中

6410是SQLITE\u IOERR\u GETTEMPPATH
,这意味着没有一个是可访问的


Android没有任何默认的Unix路径。内置数据库框架编译SQLite库的副本时使用=3。如果您想获得实际的临时文件,则应将其放入返回的任何目录中;这需要设置SQLite_TMPDIR环境变量。

Call
sqlite3_errmsg()
@CL这就是我获得“SQL逻辑错误或缺少数据库”消息的原因。您显示的代码中没有此类调用。您是正确的。发布的代码来自上一次调试迭代。我已更新代码以显示调用。
prepareSqlStatement()
do?终于又开始研究了。中间查询太大了,无法放入内存,因此我最终将PRAGMA temp_store_directory设置为/mnt/sdcard,从而更改了临时文件存储。不过,我想我需要重新编写查询,等待移动应用程序需要40分钟:-)
static void reportError(const char* message, int errorCode)
{
    std::stringstream ss;
    ss << message << errorCode;
    throw std::runtime_error(ss.str());
}