为什么Go会使用Postgresql数字&十进制列为[] uint8?

时间:2015-08-11 15:46:40

标签: 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)
  }

}

打印:

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

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

2 个答案:

答案 0 :(得分:8)

因为没有更好的解决方案。 (至少不到Go 1.5's big.Float)。还有什么其他选择?

  • 将其变为整数。显然是一个糟糕的解决方案,因为数字可以有一个小部分。

  • 将其变为float64。这是邪恶。特别是如果您正在使用资金(numericdecimal等类型的使用率最高)。

这个特定的数据库驱动程序选择返回一个包含该数字的字符串 - 让决定是否失去一些精确度(通过将float64转换为strconv gmp })或使用小数/精确数字库(如math/big$scope)。

答案 1 :(得分:0)

这是开发人员对这些问题的答案的问题:https://github.com/lib/pq/issues/648

  

为小数点使用float64类型并不安全,因为浮点数不能代表所有小数点。例如,小数支持的指数远大于浮点数,并且将浮点数的系数转换为以2为基数的表示形式时,会发生变化。将字符串转换为浮点数很简单,因此我们将保持这种行为。