package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, _ := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
// Just Query
rows, _ := db.Query("SELECT id FROM test_1 WHERE id=123456")
for rows.Next() {
var id interface{}
rows.Scan(&id)
fmt.Println("Query no args =>", id)
}
// Query with args
rows, _ = db.Query("SELECT id FROM test_1 WHERE id=?", 123456)
for rows.Next() {
var id interface{}
rows.Scan(&id)
fmt.Println("Query has args =>", id)
}
}
输出:
$ go run main.go
Query no args => [49 50 51 52 53 54]
Query has args => 123456
问题:
在我看来,"SELECT id FROM test_1 WHERE id=123456"
和"SELECT id FROM test_1 WHERE id=?", 123456
是相同的SQL查询。
为什么结果的TYPE不相同?
这是一个错误还是只是不友好的API设计?
答案 0 :(得分:1)
这与问题http://site有关。 MySQL中有两种协议:
[]byte
。可以在方法#366中找到相关的源代码。进一步转换将在textRows.readRow
期间进行,rows.Scan
是database/sql
包的一部分。这里,结果将从[]byte
转换(如果可转换)到传递给Scan
的参数类型。 binaryRows.readRow
找到。 在这个问题中,由于Scan
参数的类型为interface{}
,因此在database/sql
方面,不会发生转换。发出query without args
时,似乎驱动程序将使用文本协议,但是当查询有参数时,驱动程序将创建prepared-statement然后使用<与服务器通信< em>二进制协议。简而言之:
[]byte
→结果扫描到interface{}
→结果返回为123456
的ASCII代码(即{{ 1}})。[49 50 51 52 53 54]
)的转换→结果扫描到int64
→结果返回为interface{}
。 如果要获得相同的结果,请使用以下代码进行第一次查询(为清楚起见,省略错误处理):
int64