[英]golang mysql DESCRIBE table causes driver.Value type nil error
[英]channel of type interface not receiving value in golang with MySql
我是golang的新手。 我正在嘗試使用golang對mysql db進行並發查詢。 我知道通道可以是類型接口。 當我在RunQuery
函數中打印tableData (type map)
時,得到了結果。 我正在發送tableData
到ch
即類型接口的通道。 在函數getdataList
我在ch
沒有任何值。 我不明白我在做什么錯。
以下是我的代碼:
package main
import (
"database/sql"
"fmt"
"net/http"
_ "github.com/go-sql-driver/mysql"
"log"
)
var db *sql.DB
func getdataList(id int) {
ch := make(chan interface{})
done := make (chan bool)
RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
go func() {
for {
x, ok := <-ch //I am not getting any data in channel here
if ok {
fmt.Println(x)
}else {
fmt.Println("done")
done <- true
return
}
}
}()
}
func RunQuery (ch chan interface{}, query string, param interface{}) {
stmt, err := db.Prepare(query)
if err != nil {
panic(err.Error())
}
defer stmt.Close()
rows, err := stmt.Query(param)
columns, err := rows.Columns()
if err != nil {
fmt.Println("Failed to get columns", err)
return
}
count := len(columns)
tableData := make([]map[string]interface{}, 0)
values := make([]interface{}, count)
valuePtrs := make([]interface{}, count)
for rows.Next() {
for i := 0; i < count; i++ {
valuePtrs[i] = &values[i]
}
rows.Scan(valuePtrs...)
entry := make(map[string]interface{})
for i, col := range columns {
var v interface{}
val := values[i]
b, ok := val.([]byte)
if ok {
v = string(b)
} else {
v = val
}
entry[col] = v
}
tableData = append(tableData, entry)
}
fmt.Pritln(tableData) //here I am getting data in map
ch <- tableData
}
func dbtest(w http.ResponseWriter, req *http.Request) {
go getdataList(2)
go getdataList(3)
}
func main() {
var err error
db, err = sql.Open("mysql", "root:@/dbName")
if err != nil {
panic(err.Error())
}
defer db.Close()
http.HandleFunc("/dbTest", dbtest)
log.Fatal(http.ListenAndServe(":8080", nil))
}
您的代碼的問題在於,在可以從通道讀取數據之前,它阻塞了執行流程。 當從getdataList
調用RunQuery
時, RunQuery
嘗試通過通道ch
發送數據。 但是,從ch
不會讀取任何內容,因為要從ch
讀取的代碼位於getdataList
,並且位於對RunQuery
的調用RunQuery
。
因此, RunQuery
永遠不會返回,並且從ch
讀取的goroutine永遠不會觸發。 要解決此問題,您還可以嘗試將RunQuery
作為goroutine運行:
func getdataList(id int) {
ch := make(chan interface{})
done := make (chan bool)
// run in a goroutine
go RunQuery(ch,"select id,name, last_name,first_name from persons where id= ?", id)
go func() {
for {
x, ok := <-ch //I am not getting any data in channel here
if ok {
fmt.Println(x)
}else {
fmt.Println("done")
done <- true
return
}
}
}()
}
您的代碼中還有另一個問題。 您永遠不會關閉ch
。 這可能會導致死鎖。 最理想的位置似乎在RunQuery
:
func RunQuery (ch chan interface{}, query string, param interface{}) {
// ...
ch <- tableData
close(ch)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.