Go 中的 ODBC 返回 Null/Blank 条记录
ODBC in Go Returning Null/Blank Records
我正在尝试通过 ODBC 将 Go REST API 连接到基于 FileMaker 的后端数据库。
我已经在 Windows 上成功安装了 FileMaker ODBC 驱动程序并且 DSN 正在运行。
我正在使用 Go 中的 mgodbc
包连接到数据库。
然而,虽然连接有效(没有 运行 时间错误),但当我 运行 查询时,我只得到 blank/null 条记录。我有以下代码来创建数据库连接:
func NewDB(dataSourceName string) (*DB, error) {
db, err := sql.Open("mgodbc", dataSourceName)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
}
// TEST
return &DB{db}, nil
}
这是从我的 main
方法调用的,如下所示:db, err := md.NewDB("DSN=cet_registrations2;Uid=*****;Pwd=*****;")
。然后我调用我的查询方法之一并尝试将其读入模型 struct
。我简化了我的查询以使其更容易:
func (db *DB) GetStudent(id int) (*Student, error) {
s := new(Student)
p := new(PersonalDetails)
log.Println(id)
rows, err := db.Query("SELECT FN_Gn_Pn FROM STUDENTS")
i := 0
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
i++
err := rows.Scan(&p.FirstName)
log.Print(p.FirstName.String)
log.Printf(strconv.Itoa(i))
if err != nil {
log.Fatal(err)
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
s.ID = 34114
s.Details = p
return s, err
}
我正在阅读以下内容struct
:
import (
"database/sql"
u "sydney.edu.au/bric9018/cet.api/util"
)
type PersonalDetails struct {
// Unique identifier for person
ID int32 `json:"id,omitempty"`
// First name of person
FirstName sql.NullString `json:"firstName,omitempty"`
// Last name of person.
LastName sql.NullString `json:"lastName,omitempty"`
// Person nominated preferrered name.
PreferredName sql.NullString `json:"preferredName,omitempty"`
// Person's SSO username for University systems
Unikey sql.NullString `json:"unikey,omitempty"`
// Person's personal email
PersonalEmail sql.NullString `json:"personalEmail,omitempty"`
// Sydney University email
UniEmail sql.NullString `json:"uniEmail,omitempty"`
// Person's date of birth
Dob u.NullTime `json:"dob,omitempty"`
}
但是,当我使用 log.Print(p.FirstName.String)
打印扫描到模型中的值时,我只得到完全空白的行。我似乎没有通过扫描到我的 struct
来读回任何值。为什么是这样?
P.S。当我 运行 它在 SQL 服务器中通过针对 FileMaker DB 的链接服务器连接时,查询肯定 returns 值。
Golang odbc 驱动程序是系统 odbc 驱动程序(odbc32.dll, unixODBC
等)的包装器。如果在SQL服务器中执行查询得到任何结果,就排除了查询错误或系统驱动问题的可能性。那么问题就会出在golang的driver(mgodbc
)这边。可能的问题:
- 由于 mismatch/unsupported 数据类型,驱动程序无法转换查询结果(例如,您将数据库中的字符串 table 存储为二进制等)。所以第一次尝试是
scan the result to []byte
。
- 由于错误,驱动程序无法转换查询结果。尝试使用 another odbc driver.
由于我们无法使用有问题的数据库,因此我们无法重现该问题。要了解问题出在哪里,请使用调试器。我个人使用 Visual Studio Code. To setup the debugger, please refer to VS Code and delve debugger.
我的猜测,问题存在于 mgodbc's Next
function (line number 781-1011). The odbc's
implementation of Next
function is available here (line 35). The function relies on column.Value
函数(第 116-165 行)转换查询结果中。使用调试器,您可以观察变量、表达式并比较这些驱动程序如何处理查询结果转换。
我正在尝试通过 ODBC 将 Go REST API 连接到基于 FileMaker 的后端数据库。
我已经在 Windows 上成功安装了 FileMaker ODBC 驱动程序并且 DSN 正在运行。
我正在使用 Go 中的 mgodbc
包连接到数据库。
然而,虽然连接有效(没有 运行 时间错误),但当我 运行 查询时,我只得到 blank/null 条记录。我有以下代码来创建数据库连接:
func NewDB(dataSourceName string) (*DB, error) {
db, err := sql.Open("mgodbc", dataSourceName)
if err != nil {
return nil, err
}
if err = db.Ping(); err != nil {
return nil, err
}
// TEST
return &DB{db}, nil
}
这是从我的 main
方法调用的,如下所示:db, err := md.NewDB("DSN=cet_registrations2;Uid=*****;Pwd=*****;")
。然后我调用我的查询方法之一并尝试将其读入模型 struct
。我简化了我的查询以使其更容易:
func (db *DB) GetStudent(id int) (*Student, error) {
s := new(Student)
p := new(PersonalDetails)
log.Println(id)
rows, err := db.Query("SELECT FN_Gn_Pn FROM STUDENTS")
i := 0
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
i++
err := rows.Scan(&p.FirstName)
log.Print(p.FirstName.String)
log.Printf(strconv.Itoa(i))
if err != nil {
log.Fatal(err)
}
}
err = rows.Err()
if err != nil {
log.Fatal(err)
}
s.ID = 34114
s.Details = p
return s, err
}
我正在阅读以下内容struct
:
import (
"database/sql"
u "sydney.edu.au/bric9018/cet.api/util"
)
type PersonalDetails struct {
// Unique identifier for person
ID int32 `json:"id,omitempty"`
// First name of person
FirstName sql.NullString `json:"firstName,omitempty"`
// Last name of person.
LastName sql.NullString `json:"lastName,omitempty"`
// Person nominated preferrered name.
PreferredName sql.NullString `json:"preferredName,omitempty"`
// Person's SSO username for University systems
Unikey sql.NullString `json:"unikey,omitempty"`
// Person's personal email
PersonalEmail sql.NullString `json:"personalEmail,omitempty"`
// Sydney University email
UniEmail sql.NullString `json:"uniEmail,omitempty"`
// Person's date of birth
Dob u.NullTime `json:"dob,omitempty"`
}
但是,当我使用 log.Print(p.FirstName.String)
打印扫描到模型中的值时,我只得到完全空白的行。我似乎没有通过扫描到我的 struct
来读回任何值。为什么是这样?
P.S。当我 运行 它在 SQL 服务器中通过针对 FileMaker DB 的链接服务器连接时,查询肯定 returns 值。
Golang odbc 驱动程序是系统 odbc 驱动程序(odbc32.dll, unixODBC
等)的包装器。如果在SQL服务器中执行查询得到任何结果,就排除了查询错误或系统驱动问题的可能性。那么问题就会出在golang的driver(mgodbc
)这边。可能的问题:
- 由于 mismatch/unsupported 数据类型,驱动程序无法转换查询结果(例如,您将数据库中的字符串 table 存储为二进制等)。所以第一次尝试是
scan the result to []byte
。 - 由于错误,驱动程序无法转换查询结果。尝试使用 another odbc driver.
由于我们无法使用有问题的数据库,因此我们无法重现该问题。要了解问题出在哪里,请使用调试器。我个人使用 Visual Studio Code. To setup the debugger, please refer to VS Code and delve debugger.
我的猜测,问题存在于 mgodbc's Next
function (line number 781-1011). The odbc's
implementation of Next
function is available here (line 35). The function relies on column.Value
函数(第 116-165 行)转换查询结果中。使用调试器,您可以观察变量、表达式并比较这些驱动程序如何处理查询结果转换。