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
相关产品推荐
相关产品推荐

