Go语言使用URL.Query().Get()的值填充SELECT语句不生效如何解决
排查步骤
- 第一步:不要吞掉所有错误,把所有忽略的error都打印出来,确认是哪一步执行失败
你现在代码里db.Query、rows.Columns的返回错误都用_丢弃了,执行报错完全感知不到。另外sql.Open仅初始化数据库驱动,不会真的建立连接,需要额外调用db.Ping()确认连接正常。 - 第二步:打印拼接完成的完整SQL语句,确认table参数是否正常拼接
加一行log.Println("执行的SQL:", "SELECT * FROM "+table),看输出的SQL是否符合预期,排查table参数是否携带空格、不可见字符等问题。 - 第三步:确认返回响应时没有报错
如果db.Query执行失败会返回nil的rows,此时调用rows.Columns会触发空指针panic,导致HTTP请求直接返回500错误,前端自然看不到内容。
修复后的参考代码
func startHandler(w http.ResponseWriter, r *http.Request) { conn_str := dbuser + ":" + dbpass + "@tcp(" + dbhost + ":" + dbport + ")/" + dbdb log.Println(conn_str) db, err := sql.Open("mysql", conn_str) if err != nil { log.Println("DB Error - 驱动初始化失败:", err) fmt.Fprintf(w, "数据库初始化失败: %v", err) return } defer db.Close() // 确认数据库连接正常 if err = db.Ping(); err != nil { log.Println("DB Error - 连接失败:", err) fmt.Fprintf(w, "数据库连接失败: %v", err) return } table := r.URL.Query().Get("table") log.Println("获取到的table参数:", table) // 打印完整SQL确认拼接结果 sqlStr := "SELECT * FROM " + table log.Println("执行SQL:", sqlStr) rows, err := db.Query(sqlStr) if err != nil { log.Println("查询失败:", err) fmt.Fprintf(w, "查询执行失败: %v", err) return } defer rows.Close() // 别忘了关闭rows避免资源泄漏 cols, err := rows.Columns() if err != nil { log.Println("获取列名失败:", err) fmt.Fprintf(w, "获取列名失败: %v", err) return } fmt.Fprintf(w, "%s\n", cols) }
重要注意事项
直接将用户传入的参数拼接进SQL语句存在严重的SQL注入风险,恶意用户可以传入构造好的table参数删除数据表、拖取全量数据,生产环境必须严格校验table参数的合法性,比如限定只能在预设的表名列表中选择,禁止使用直接拼接的方式操作SQL。
内容的提问来源于stack exchange,提问作者sippi181
相关产品推荐
相关产品推荐

