2017-04-26 87 views
0

我试图通过ODBC将Go REST API连接到基于后端FileMaker的数据库。ODBC返回空/空记录

我在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。为什么是这样?

P.S.当我在SQL Server中通过链接服务器连接对FileMaker数据库运行时,查询肯定会返回值。

+0

如果您将该值扫描到具有'[] byte'类型而不是'sql.NullString'的变量,您会得到什么? – putu

+0

如果将其更改为'[] byte'并使用不带字符串的相同打印语句('log.Print(p.FirstName)'),则不会在数组中找到任何值,即打印出[]。 – Ben

+0

如果将驱动程序从'mgodbc'更改为['odbc'驱动程序](https://github.com/alexbrainman/odbc)(只更改导入部分)? – putu

回答

1

Golang odbc驱动程序是系统的odbc驱动程序(odbc32.dll, unixODBC等)的包装。如果在SQL Server中执行查询时得到任何结果,则消除查询错误或系统驱动程序问题的可能性。那么问题将出现在golang的驱动程序(mgodbc)一侧。可能的问题:

  1. 由于不匹配/不支持的数据类型导致驱动程序无法转换查询结果(例如,您将字符串作为二进制等存储在数据库表中)。所以第一次尝试是scan the result to []byte
  2. 由于错误导致驱动程序无法转换查询结果。尝试使用another odbc driver

由于问题数据库不适用于我们,因此我们无法重现该问题。要了解问题所在,请使用调试器。我个人使用Visual Studio Code。要设置调试器,请参考VS Code and delve debugger

我的猜测,问题存在于mgodbc's Next函数(行号781-1011)。 函数的odbc's函数可用here(第35行)。该函数依赖column.Value函数(第116-165行)来转换查询结果。使用调试器,您可以观察变量,表达式并比较这些驱动程序处理查询结果转换的方式。