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

SQLite插入后查询Name与Director字段值异常一致问题求助

问题原因分析

你的问题根源在于SQLite的sqlite3_column_text返回的指针是临时缓冲区的引用,再搭配CHAR(255)字段的特性,最终导致字符串读取时出现了覆盖问题。

具体拆解一下:

  1. 你用CHAR(255)定义字段,SQLite会自动用空格把字符串填充到255个字符长度,而这些填充的空格并不是C字符串的终止符\0;
  2. sqlite3_column_text返回的指针指向SQLite内部的临时缓冲区,每次调用sqlite3_column_*系列函数(包括多次调用sqlite3_column_text)时,这个缓冲区的内容会被覆盖;
  3. 你的查询代码里,先调用sqlite3_column_text(selectStatement, 1)获取Name的指针,但没有立即转成Swift String保存;之后调用sqlite3_column_text(selectStatement, 3)获取Director的指针,此时临时缓冲区已经被Director的内容覆盖。后续用这两个指针创建String时,两个指针都指向了最后一次调用的内容(也就是Director的值);
  4. 再加上CHAR(255)的空格填充,读取Name字段时因为没有\0终止符,String会一直读取内存直到遇到终止符,刚好后续的Director字段内容就在内存中,所以最终Name的内容被Director覆盖,且长度和原Name一致。
解决方法

针对这个问题,有两个关键修复点:

1. 立即转换临时指针为Swift String

每次调用sqlite3_column_text后,立刻把它转换成Swift String并保存,避免临时缓冲区被后续调用覆盖。

修改selectAllMovie方法里的循环部分:

while sqlite3_step(selectStatement) == SQLITE_ROW {
    // 立即转换每个列的内容并保存,避免指针被覆盖
    let id = sqlite3_column_int(selectStatement, 0)
    
    // 处理Name字段
    let nameCString = sqlite3_column_text(selectStatement, 1)
    let name = nameCString != nil ? String(cString: nameCString!) : ""
    
    let year = sqlite3_column_int(selectStatement, 2)
    
    // 处理Director字段
    let directorCString = sqlite3_column_text(selectStatement, 3)
    let director = directorCString != nil ? String(cString: directorCString!) : ""
    
    let movie = Movie(
        ID: id,
        name: name,
        year: year,
        director: director
    )
    
    print("Name --> \(name)")
    print("Director --> \(director)")
    print("Name value out is: \(movie.name), Director Value out is: \(movie.director)")
    
    result.append(movie)
}

2. 改用TEXT类型替代CHAR(255)(推荐)

CHAR(n)类型强制填充空格的特性不仅浪费存储空间,还容易引发C字符串读取问题。SQLite中更推荐用TEXT类型存储字符串,它会自动适配字符串长度,不需要填充空格,从根源上避免这类内存读取问题。

修改createMovieTable方法的表结构:

let createTableQuery = """
CREATE TABLE Movie (
ID INTEGER PRIMARY KEY NOT NULL,
Name TEXT,
Year INTEGER,
Director TEXT
);
"""
验证修复效果

修改完成后重新运行插入和查询代码,就能看到Name和Director字段的值可以正确区分,不会再出现互相覆盖的情况了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:24:59