英文:
ODBC in Go Returning Null/Blank Records
问题
我正在尝试将一个基于 FileMaker 的后端数据库通过 ODBC 连接到 Go REST API。
我已经成功在 Windows 上安装了 FileMaker ODBC 驱动程序,并且 DSN 正常工作。
我正在使用 Go 中的 mgodbc
包来连接数据库。
然而,虽然连接成功(没有运行时错误),但是当我运行查询时,我只能得到空白/空记录。我有以下代码来创建数据库连接:
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
中。为什么会这样?
附注:当我在 SQL Server 中通过链接服务器连接到 FileMaker DB 并运行查询时,查询确实返回值。
英文:
I am trying to connect a Go REST API to a backend FileMaker based database over ODBC.
I have successfully installed the FileMaker ODBC drivers on Windows and the DSN is working.
I am using the mgodbc
package in Go to connect to the DB.
However, while the connection works (no runtime error), I just get blank/null records back when I run a query. I have the following code to create a DB connection:
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
}
This gets called from my main
method as follows: db, err := md.NewDB("DSN=cet_registrations2;Uid=*****;Pwd=*****;")
. I then call one of my query methods and try to read it into a model struct
. I have simplified my query to make it easier:
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
}
and I am reading into the following 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"`
}
However, I just get completely blank rows when I print the value scanned into the model using log.Print(p.FirstName.String)
. I don't seem to be getting any values read back by scan into my struct
. Why is this?
P.S. the query definitely returns values when I run it in SQL Server over a linked server connection against the FileMaker DB.
答案1
得分: 1
Golang的ODBC驱动是系统ODBC驱动(odbc32.dll, unixODBC
等)的包装器。如果在SQL Server中执行查询时得到任何结果,那么可以排除查询错误或系统驱动问题的可能性。那么问题可能出在Golang的驱动程序(mgodbc
)方面。可能的问题包括:
- 由于数据类型不匹配/不支持(例如,将字符串存储为二进制等),驱动程序无法转换查询结果。因此,首先尝试将结果扫描到
[]byte
。 - 由于错误,驱动程序无法转换查询结果。尝试使用另一个ODBC驱动程序。
由于我们无法访问相关数据库,因此无法重现问题。要了解问题所在,请使用调试器。我个人使用Visual Studio Code。要设置调试器,请参考VS Code和Delve调试器。
我猜测问题存在于mgodbc
的Next函数(第781-1011行)。odbc
的Next
函数的实现在这里(第35行)。该函数依赖于column.Value
函数(第116-165行)来转换查询结果。使用调试器,您可以观察变量、表达式,并比较这些驱动程序如何处理查询结果的转换。
英文:
Golang odbc driver is a wrapper of system's odbc driver (odbc32.dll, unixODBC
, etc). If you got any result when executing the query in SQL Server, it eliminates the probability of query error or system's driver problem. Then the problem will be in golang's driver (mgodbc
) side. Possible issues:
- The driver failed to convert query result due to mismatch/unsupported data type (e.g. you store the string in the database table as binary, etc). So the first try was
scan the result to []byte
. - The driver failed to convert query result due to bug. Try using another odbc driver.
Because the database in question is not available to us, its impossible for us to reproduce the problem. To learn what was the problem, please use debugger. Personally I'm using Visual Studio Code. To setup the debugger, please refer to VS Code and delve debugger.
My guess, the problem exist in 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
function (line 116-165) to convert the query result. Using debugger, you can observe variable(s), expression(s) and compare how these drivers handle query result conversion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论