I have an MSSQL procedure that returns some kind of data, where the first row is uuid. Example below:

According to manual I have defined structure and pass it into rows.Scan. Here is the sample code:
The base structure
package models
import (
"fmt"
"database/sql"
"clients"
"db"
)
type Base struct {
rows *sql.Rows
}
func (base *Base) ExecuteQuery(sql string, values ...interface{}) (err error) {
base.rows, err = db.Connection.Raw(sql, values...).Rows()
if err != nil {
return err
}
return nil
}
And the Company model
package models
import (
"time"
"github.com/satori/go.uuid"
)
type Companies struct {
Base `json:"-"`
Items []interface{} `json:"readers"`
}
type CompanyItem struct {
GUID uuid.UUID `json:"guid"`
Name []byte `json:"name"`
Inn []byte `json:"inn"`
Kpp []byte `json:"kpp"`
IsOrganization int `json:"is_organization"`
LastName []byte `json:"last_name"`
FirstName []byte `json:"first_name"`
UpdatedAt time.Time `json:"-"`
}
func SyncCompanies(since time.Time) (bool, error) {
companies := &Companies{}
err := companies.ExecuteQuery("exec pr_Site_Upload_Company @DateB = ?, @DateE = ?", since, time.Now())
defer companies.rows.Close()
if err != nil {
return false, err
}
err = companies.processRows()
if err != nil {
return false, err
}
// Here goes some code
return true, nil
}
func (companies *Companies) processRows() error {
for companies.rows.Next() {
item := &CompanyItem{}
err := companies.rows.Scan(&item.GUID, &item.Name, &item.Inn, &item.Kpp, &item.IsOrganization,
&item.LastName, &item.FirstName, &item.UpdatedAt)
if err != nil {
return err
}
companies.Items = append(companies.Items, item)
}
return nil
}
Everything is ok except GUID field. item.GUID does not match row's GUID. But strange - every time I execute query it returns same GUID if row didn't change, like there is some kind of algorithm which transforms row's guid into the new one
So the question is how to fix that? I couldn't find solution :(
I have found the solution, may be you will realise this in your project. The reason of this issue was that MsSQL stores uuid in specific format, so we need to read bytes in a non-standard order.
So the simple version of my solution looks like this:
func FormatUUID(uuid []byte) (string) {
x1 := binary.LittleEndian.Uint32(uuid[0:])
x2 := binary.LittleEndian.Uint16(uuid[4:])
x3 := binary.LittleEndian.Uint16(uuid[6:])
x4 := binary.BigEndian.Uint16(uuid[8:])
x5 := binary.BigEndian.Uint16(uuid[10:])
x6 := binary.BigEndian.Uint32(uuid[12:])
return fmt.Sprintf("%08x-%04x-%04x-%04x-%04x%08x", x1, x2, x3, x4, x5, x6)
}
Thanks for the workaround. @RomanZagudaev It worked perfectly.
Is there a proper approach to read uniqueidentifier been implemented into the package github.com/jinzhu/gorm/dialects/mssql? //cc: @jinzhu Thanks
Most helpful comment
I have found the solution, may be you will realise this in your project. The reason of this issue was that MsSQL stores uuid in specific format, so we need to read bytes in a non-standard order.
So the simple version of my solution looks like this: