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

Go中使用SQL预处理语句查询SQLite时出现无结果集错误

解决Go中SQLite预处理语句LIKE查询无结果的问题

你的问题核心是预处理语句中LIKE子句的占位符使用方式错误:原代码里的LIKE '%install ?%'会让SQLite把?当成字符串的一部分,而非替换为传入的pkg参数。实际执行的查询是找包含%install ?%字面量的行,自然匹配不到目标数据。

以下是两种可行的修复方案:

方法1:在参数中拼接通配符

修改SQL语句让占位符独立存在,然后在传入参数时把通配符和包名拼接(注意Go中字符串的%需要用%%转义):

func getTransactionId(pkg string, db *sql.DB) (int, error) {
    var id int
    fmt.Println("Package is:", pkg)
    fmt.Println("Db is this:", db)
    // 占位符独立,参数包含通配符
    sqlStatement := `SELECT tid FROM trans_cmdline WHERE cmdline LIKE ? ORDER BY tid DESC LIMIT 1`
    // 拼接通配符,Go中%需要用%%转义
    likePattern := fmt.Sprintf("%%install %s%%", pkg)
    err := db.QueryRow(sqlStatement, likePattern).Scan(&id)
    if err != nil {
        fmt.Println("Err:", err)
    }
    switch err {
    case sql.ErrNoRows:
        fmt.Println("ID is this:", id)
        fmt.Println("No rows were returned:", err)
        return 0, err
    case nil:
        return id, nil
    default:
        return 0, err
    }
}

方法2:在SQL中用字符串连接符拼接通配符

利用SQLite的字符串连接运算符||,把通配符和占位符拼接,直接传入原始包名参数:

func getTransactionId(pkg string, db *sql.DB) (int, error) {
    var id int
    fmt.Println("Package is:", pkg)
    fmt.Println("Db is this:", db)
    // 用SQLite的||拼接通配符和占位符
    sqlStatement := `SELECT tid FROM trans_cmdline WHERE cmdline LIKE '%install ' || ? || '%' ORDER BY tid DESC LIMIT 1`
    err := db.QueryRow(sqlStatement, pkg).Scan(&id)
    if err != nil {
        fmt.Println("Err:", err)
    }
    switch err {
    case sql.ErrNoRows:
        fmt.Println("ID is this:", id)
        fmt.Println("No rows were returned:", err)
        return 0, err
    case nil:
        return id, nil
    default:
        return 0, err
    }
}

关键注意点

预处理语句的占位符?必须作为独立表达式存在,不能嵌套在单引号包裹的字符串常量中。数据库只会替换独立的占位符,不会解析字符串内部的?。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 12:23:20