返回空/空白记录中的ODBC

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.

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:

  1. 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.
  2. 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.