Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help needed with uniqueidentifier #56

Closed
scohen28 opened this issue Jul 30, 2014 · 4 comments
Closed

Help needed with uniqueidentifier #56

scohen28 opened this issue Jul 30, 2014 · 4 comments

Comments

@scohen28
Copy link

I'm retrieving the ID from a sql server database as follows:

import ("github.com/nu7hatch/gouuid")
var theID []byte
err := db.QueryRow("select id from table where item='xxx').Scan(&theID)
fmt.Println(theID)
idStr, _ := uuid.Parse(theID)
fmt.Println(idStr)

Prints:
[249 214 3 106 70 136 42 75 185 33 204 184 168 141 203 14]
f9d6036a-4688-2a4b-b921-ccb8a88dcb0e

When I directly query the table using Sql Management Studio, for the same query I get:
6A03D6F9-8846-4B2A-B921-CCB8A88DCB0E

I also tried the following, but it returns the same 'f9d...' value
b := theID
b[6] = (b[6] & 0x0F) | 0x40
b[8] = (b[8] &^ 0x40) | 0x80
theIDStr := fmt.Sprintf("%x-%x-%x-%x-%x", b[:4], b[4:6], b[6:8], b[8:10]

What is the correct parsing function to use on the returned []byte to resolve to the same value that Sql Server is presenting?

@denisenkom
Copy link
Owner

First four parts of guid are integers 32 16 16 16 bit respectively, looks like Parse function incorrectly interprets data big-endian/little-endian (http://en.wikipedia.org/wiki/Endianness) mixup. You can swap order of bytes to get correct byte order for your function or maybe Parse function can take parameters specifying endianness of the input.

@scohen28
Copy link
Author

Thanks - I was playing around with this and had come up with:
b := orgID
b[0], b[1], b[2], b[3] = b[3], b[2], b[1], b[0]
b[4], b[5] = b[5], b[4]
b[6], b[7] = b[7], b[6]

and that resolved it.

My setup is running a GO program on a Mac and retrieving (obviously) from a Windows Machine. If the program was to be cross-compiled onto PC, Mac, Linux (I don't have a PC to test on) - would I need to test for the OS and if PC not do the byte swapping?

@sachin-walia
Copy link

Thanks @scohen28 this was really helpful.

petertranfl added a commit to petertranfl/go-mssqldb that referenced this issue Jul 25, 2019
When grabbing the GUID from the MS SQL database, the first half of the GUID becomes scrambled, due to the parser mixing up the Little Endian and Big Endian data types, and this is due to the way Microsoft handles GUIDs.

The proposed pull request correctly swaps the byte order by implementing the fix proposed in denisenkom#56
odeke-em pushed a commit to orijtech/go-mssqldb that referenced this issue Jul 26, 2020
@shueybubbles
Copy link
Contributor

@kardianos one problem with requiring an app to scan to *mssql.UniqueIdentifier instead of *interface{} is the scanner doesn't currently support a null uniqueidentifier.
select convert(uniqueidentifier, null) will fail
sql: Scan error on column index 0, name "": mssql: cannot convert <nil> to UniqueIdentifier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants