dqrm8199
2017-10-09 16:56
浏览 76

无效的内存地址或nil指针取消引用golang数据库

I searched a lot to find solution for this error, but nothing worked. when I use the query inside main function it works fine, but when I pass it to the Group function it panics. here is the code:

package main

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "net/http"
    "strconv"
    "strings"
)

var db *sql.DB
var err error

type Row struct {
    Id         int
    Title      string `json:"title,omitempty"`
    Adress     string `json:"adress,omitempty"`
    Tozihat    string `json:"tozihat,omitempty"`
    Mobile     string `json:"mobile,omitempty"`
    Phone      string `json:"phone,omitempty"`
    Mapid      string `json:"mapid,omitempty"`
    Location   string `json:"location,omitempty"`
    Keywords   string `json:"keyword,omitempty"`
    Imagepath1 string `json:"imagepath1,omitempty"`
    Imagepath2 string `json:"imagepath2,omitempty"`
    Category   string `json:"category,omitempty"`
    Catid      int    `json:"catid,omitempty"`
}

func Group(res http.ResponseWriter, req *http.Request) {
    u := req.URL.RequestURI()
    Id := strings.Split(u, "/")[2]
    catId, errconv := strconv.Atoi(Id)
    if errconv != nil {
            fmt.Println(errconv)
    }
    rows, errrows := db.Query("select title, location, category from Total where catID=(?)", catId)
    if errrows != nil {
            fmt.Println(errrows)

    }

    defer rows.Close()
    var results []Row
    var result Row

    for rows.Next() {

            errr := rows.Scan(&result.Title, &result.Location, &result.Category)
            if errr != nil {
                    fmt.Println(errr)

            }

            results = append(results, result)
    }
    fmt.Println(results)
    jsonresults, errj := json.Marshal(results)
    if errj != nil {
            fmt.Print("error marshaling results", errj)
    }
    res.Header().Set("Content-Type", "application/json")

    res.Write(jsonresults)

}

func main() {
    http.HandleFunc("/group/", Group)

    http.ListenAndServe(":9001", nil)

    db, err = sql.Open("mysql", "root:456852@/bartarinha")
    if err != nil {
            fmt.Println(err)
    }
    defer db.Close()
    errPing := db.Ping()
    if errPing != nil {
            fmt.Println(errPing)
    }
}

any help is appreciated. the error looks like this: 2017/10/09 22:43:44 http: panic serving [::1]:41618: runtime error: invalid memory address or nil pointer dereference goroutine 7 [running]: net/http.(*conn).serve.func1(0xc420088820) /usr/local/go/src/net/http/server.go:1721 +0xd0

panic(0x688060, 0x81fc40)
    /usr/local/go/src/runtime/panic.go:489 +0x2cf
database/sql.(*DB).conn(0x0, 0x7fe580, 0xc4200102b0, 0x1, 0x6dac6a, 
0xd10000000000000e, 0xe)
    /usr/local/go/src/database/sql/sql.go:896 +0x3a
database/sql.(*DB).query(0x0, 0x7fe580, 0xc4200102b0, 0x6e7aff, 0x3b,                 
0xc420047aa8, 0x1, 0x1, 0x1, 0xc42002cc00, ...)
    /usr/local/go/src/database/sql/sql.go:1245 +0x5b
database/sql.(*DB).QueryContext(0x0, 0x7fe580, 0xc4200102b0, 0x6e7aff, 
0x3b, 0xc420047aa8, 0x1, 0x1, 0xc4200e01a0, 0xc42003ca40, ...)
    /usr/local/go/src/database/sql/sql.go:1227 +0xb8
database/sql.(*DB).Query(0x0, 0x6e7aff, 0x3b, 0xc42003caa8, 0x1, 0x1, 
0x8, 0xc4200d8038, 0xc420016e40)
    /usr/local/go/src/database/sql/sql.go:1241 +0x82
main.Group(0x7fe080, 0xc4200f82a0, 0xc42000a900)
    /home/behrooz/gp_projects/src/samples/kabootar/main.go:40 +0x230
net/http.HandlerFunc.ServeHTTP(0x6e9d38, 0x7fe080, 0xc4200f82a0, 
0xc42000a900)
    /usr/local/go/src/net/http/server.go:1942 +0x44
net/http.(*ServeMux).ServeHTTP(0x8293c0, 0x7fe080, 0xc4200f82a0, 
0xc42000a900)
    /usr/local/go/src/net/http/server.go:2238 +0x130
net/http.serverHandler.ServeHTTP(0xc4200942c0, 0x7fe080, 0xc4200f82a0, 
0xc42000a900)
    /usr/local/go/src/net/http/server.go:2568 +0x92
net/http.(*conn).serve(0xc420088820, 0x7fe540, 0xc420014940)
    /usr/local/go/src/net/http/server.go:1825 +0x612
created by net/http.(*Server).Serve
    /usr/local/go/src/net/http/server.go:2668 +0x2ce
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dpjtn48868 2017-10-09 21:21
    已采纳

    So the crash is caused by the db pointer being nil. This means code which tries to use that connection on line 40 causes a panic.

    rows, errrows := db.Query(...
    

    The db pointer is nil because, as Peter pointed out, http.ListenAndServe is blocking, which means nothing after it will run.

    Try running this example locally to see the problem:

    package main
    
    import (
        "net/http"
    )
    
    func Group(res http.ResponseWriter, req *http.Request) {
        println("group handler")
    }
    
    func main() {
        http.HandleFunc("/group/", Group)
        err := http.ListenAndServe(":9001", nil)
        if err != nil {
          panic(err)
        }
        println("Running code after ListenAndServe (only happens when server shuts down)")
    }
    

    You won't see the Running code message.

    点赞 打赏 评论

相关推荐 更多相似问题