Go / GoLang在MySQL中存储二进制数据

时间:2013-11-10 06:23:08

标签: mysql go

我正在使用http://github.com/go-sql-driver/mysql

中的MySQL驱动程序

我需要在BINARY(4)列中存储MySQL中IP地址的二进制表示。

为此,我尝试过:

    startSlice := net.ParseIP(rangeStart).To4()
    var startBytes [4]byte
    copy(startSlice[:], startBytes[0:4])

    endSlice := net.ParseIP(rangeEnd).To4()
    var endBytes [4]byte
    copy(endSlice[:], endBytes[0:4])

    r, e := db.Exec("UPDATE AIPRangesBlocks SET BinRangeStart = ?, BinRangeEnd = ? WHERE IPGRID = ?", startBytes, endBytes, id)
    fmt.Println("result of update:", r)
    if e != nil {
        fmt.Println(e)
    }

请注意,我使用copy命令将[]字节切换转换为简单的[4]字节数组,但是我收到此错误:

sql: converting Exec argument #0's type: unsupported type [4]uint8, a array

如果我直接将其作为net.ParseIP(“some_ip”)。To4(),我收到此错误:

sql: converting Exec argument #0's type: unsupported type net.IP, a slice

如何发送二进制数据?

修改

好的,如果我使用十六进制字符串,它将执行查询,但我没有在检索时获得正确的值。

我尝试了hex.EncodeToString()和“0x”+ hex.EncodeToString(),但两者都没有正常工作。

以下是一个例子:

66.182.64.0 becomes 42b64000

如果我在MySQL列中存储“42b64000”,我会回来:

52 50 98 54

如果我在MySQL列中存储“0x42b64000”,我会回来:

48 120 52 50

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

如果你在我的MySQL专栏中存储“42b64000”,你会回来:

52 50 98 54

解码为ASCII,这是你给它的字符串的开头,例如

"42b6"

这表明将IP地址片作为字符串传递将起作用,例如

startSlice := net.ParseIP(rangeStart).To4()
endSlice := net.ParseIP(rangeEnd).To4()
r, e := db.Exec("UPDATE AIPRangesBlocks SET BinRangeStart = ?, BinRangeEnd = ? WHERE IPGRID = ?", string(startSlice), string(endSlice), id)
fmt.Println("result of update:", r)
if e != nil {
    fmt.Println(e)
}

在go字符串中本质上是[]byte的只读版本,你可以在它们之间进行转换而没有任何问题(除了一点内存复制)。希望MySQL驱动程序中的引用可以处理字符串中的NUL。

答案 1 :(得分:0)

您可以尝试将其存储为encoding/binary的uint32:binary.LittleEndian.Uint32(net.ParseIP(rangeStart).To4())binary.LittleEndian.PutUint32(destinationSlice, colValue)。 如果LittleEndian为您的其他应用程序提供了错误的结果,请改为使用BigEndian

答案 2 :(得分:0)

您将其转换为HEX字符串是正确的。

以下是我如何解决它(对于IPv4和IPv6):

  1. 假设您的表格是:
  2.   

    CREATE TABLE ip_addr(ip VARBINARY(16));

    1. 按如下方式准备INSERT或UPDATE语句:
    2.   

      stmt:= db.Prepare(" INSERT INTO ip_addr(ip)VALUES(UNHEX(?))")

      1. 在' Go'代码:
      2.  if ip.To4() != nil {
                        ip_hex = hex.EncodeToString(ip.To4())
         } else {
                        ip_hex = hex.EncodeToString(ip.To16())
         }
         stmt.Exec(ip_hex)