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

SQLite获取本周(周一为一周首日)成本总和返回0问题排查

本周成本总和方法返回0的问题排查与解决

我正在编写一个Objective-C方法,用来返回Cost表中本周(周一为一周第一天)的所有成本总和,但这个方法始终返回0,实在搞不懂哪里出问题了。

数据库信息

数据库结构

数据库结构

数据内容

数据内容

我的代码实现

- (float)getthisweekscosts { 
    float sumprice = 0; 
    // We initialize the total price for all the rows 
    NSString *getcurrentcost = [NSString stringWithFormat:@"%@", @"SELECT COSTAMOUNT FROM COST WHERE DATE > DATE('now', 'weekday 0', '-7 days')"]; 
    const char *query_stmt_budget = [getcurrentcost UTF8String]; 
    if (sqlite3_prepare_v2(costDB,query_stmt_budget, -1, &statement, NULL) == SQLITE_OK){ 
        while (sqlite3_step(statement) == SQLITE_ROW){ 
            NSString *currentcost = [NSString stringWithFormat:@"%s",(const char *) sqlite3_column_text(statement, 0)]; 
            sumprice += [currentcost floatValue]; 
        } 
        sqlite3_finalize(statement); 
    } 
    sqlite3_close(costDB); 
    return sumprice; 
}

问题排查与解决思路

我来帮你捋捋这个问题哈,方法返回0大概率是没查到数据或者数据读取错误,咱们一步步来:

1. SQL查询条件的坑

你当前的SQL语句是SELECT COSTAMOUNT FROM COST WHERE DATE > DATE('now', 'weekday 0', '-7 days'),这里有两个关键问题:

  • SQLite里weekday 0代表的是周日,不是周一!你要把一周第一天设为周一的话,得用weekday 1。
  • 这个条件是取「过去7天到现在」的数据,不是严格的「本周(周一到当前)」范围,很可能漏了本周一的部分数据,或者包含了上周日的数据。

给你个精准的SQL写法,确保只取本周一到现在的所有数据:

SELECT COSTAMOUNT FROM COST 
WHERE DATE >= DATE('now', '-', (strftime('%w', 'now') + 6) % 7 || ' days')

解释下:strftime('%w', 'now')会返回0(周日)到6(周六)的数字,(strftime('%w', 'now') + 6) % 7的作用是把任何日期都转成距离本周一的天数,减去这个天数就能得到本周一的日期,这样不管今天是周几,都能精准匹配本周的数据。

2. 数据读取方式错误

从数据库结构看,COSTAMOUNT是REAL类型(浮点型),但你用sqlite3_column_text把它转成字符串再转float,这中间很容易出问题(比如数值存储格式导致字符串转换失败)。直接用sqlite3_column_double读取才是正确的姿势:

// 替换原来的读取代码
sumprice += sqlite3_column_double(statement, 0);

3. 数据库连接与错误排查

你的代码没做错误日志,万一SQL语句编译失败根本不知道!建议加上错误输出,方便排查:

int prepareResult = sqlite3_prepare_v2(costDB, query_stmt_budget, -1, &statement, NULL);
if (prepareResult == SQLITE_OK){
    // 循环读取数据
} else {
    NSLog(@"SQL编译失败:%s", sqlite3_errmsg(costDB));
}

另外,sqlite3_close(costDB)如果放在这里,要是costDB是全局的数据库连接,后续操作会直接报错,建议确认数据库连接的管理逻辑,不要随便关闭。

4. 日期格式校验

最后要确认你的DATE字段是不是YYYY-MM-DD格式!SQLite的DATE()函数只认这个格式,如果你的日期是MM/DD/YYYY或者其他格式,条件判断会完全失效,查不到任何数据。

你可以先在SQLite可视化工具里跑一遍你的查询语句,看看有没有返回结果——如果工具里能查到数据,那就是代码读取的问题;如果工具里也查不到,那就是SQL条件或者日期格式的问题。

修正后的完整代码

- (float)getthisweekscosts { 
    float sumprice = 0; 
    // 精准获取本周一至今的成本数据
    NSString *sql = @"SELECT COSTAMOUNT FROM COST WHERE DATE >= DATE('now', '-', (strftime('%w', 'now') + 6) % 7 || ' days')"; 
    const char *query_stmt = [sql UTF8String]; 
    sqlite3_stmt *statement = NULL;
    
    int prepareResult = sqlite3_prepare_v2(costDB, query_stmt, -1, &statement, NULL);
    if (prepareResult == SQLITE_OK){ 
        while (sqlite3_step(statement) == SQLITE_ROW){ 
            // 直接读取REAL类型数值,避免字符串转换错误
            sumprice += sqlite3_column_double(statement, 0); 
        } 
        sqlite3_finalize(statement); 
    } else {
        NSLog(@"SQL编译错误:%s", sqlite3_errmsg(costDB));
    } 
    
    // 注意:如果costDB是全局连接,不要在这里关闭!
    // sqlite3_close(costDB); 
    return sumprice; 
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:10:05