为什么Go将Postgresql数字和十进制列视为[] uint8?

5 postgresql go postgresql-9.4

我不确定这是Go中的错误还是我不理解的错误.我有以下内容:

package main

import (
  "database/sql"
  "log"
  "reflect"

  _ "github.com/lib/pq"
)

func main() {
  Db, err := sql.Open("postgres", "user=yoitsme password=openupitsme host=x.x.x.x dbname=mydb")
  if err != nil {
    log.Println(err)
  }
  rows, err := Db.Query("SELECT 1.3250::numeric, 8.548::decimal, 908.234::float, 1234::integer")
  defer rows.Close()
  for rows.Next() {
    var col1, col2, col3, col4 interface{}
    if err := rows.Scan(&col1, &col2, &col3, &col4); err != nil {
      log.Println(err)
    }
    log.Println(col1, reflect.TypeOf(col1))
    log.Println(col2, reflect.TypeOf(col2))
    log.Println(col3, reflect.TypeOf(col3))
    log.Println(col4, reflect.TypeOf(col4))
  }
  if err = rows.Err(); err != nil {
    log.Println(err)
  }

}
Run Code Online (Sandbox Code Playgroud)

这打印:

2015/08/11 09:35:47 [49 46 51 50 53 48] []uint8
2015/08/11 09:35:47 [56 46 53 52 56] []uint8
2015/08/11 09:35:47 908.234 float64
2015/08/11 09:35:47 1234 int64
Run Code Online (Sandbox Code Playgroud)

所以,我得到[] uint8(例如一个字符串)作为实际数字的前两列.最后两列是预期的.根据Postgresql,Numeric和Decimal类型是SQL标准的一部分.那么,为什么Go不遵循他们的数据库/ sql包中的SQL标准呢?是因为Go没有内置的"Decimal"类型吗?由于语言的缺点,数据库/ sql包将数字转换为字符串似乎是错误的....

Ain*_*r-G 9

因为没有更好的解决方案.(至少直到去1.5big.Float).有什么其他选择吗?

  • 把它变成一个整数.显然是一个糟糕的解决方案,因为数字可以有一个小部分.

  • 把它变成一个float64.这是邪恶的.特别是如果你正在使用金钱(类型numericdecimal使用最多的类型).

这个特定的数据库驱动程序选择返回一个包含该数字的字符串 - 让决定是否丢失一些精度(通过将其转换为float64with strconv)或使用小数/精确数字库(如gmpmath/big).

  • `big.Float`是一个二进制浮点数,不适合表示具有固定小数精度的数字. (7认同)
  • 实际上,PostgreSQL在线路上发送`numeric`和`decimal`作为文本,除非你使用二进制协议选项.所以Go驱动程序只是没有将PostgreSQL发送到其他任何东西,因为没有合适的原生类型.它正在做正确的事情,如果/当Go获得本机任意精度十进制浮点数据类型时,应该只做其他事情. (7认同)
  • @kristen我不认为这是Go的缺点.这些较大/较高精度数值类型都不是任何语言的本机.这是Postgresql驱动程序的作者做出了这个决定.如果他们想要做一些更明智的事情,他们可以在Go中提供几种类型来托管他们没有兼容本地人的类型. (5认同)