1 回答
TA贡献1833条经验 获得超4个赞
125.00向postgres 类型的列中插入一个值的最简单方法是numeric在 Go 中使用 float 类型。这是开箱即用的,因此无需实现任何类型的自定义接口。
例如:
CREATE TABLE t (
id serial PRIMARY KEY
, amount numeric(15,4) NOT NULL
-- ...
);
data := []byte(`{"amount": 125.00}`)
var obj struct {
Amount float64 `json:"amount"`
}
if err := json.Unmarshal(data, &obj); err != nil {
panic(err)
}
_, err := db.Exec(`INSERT INTO t (amount) VALUES ($1)`, obj.Amount)
然而,浮点类型容易出现舍入误差,因此存储货币金额的常见做法是使用整数来表示以分为单位的值。例如125.00变成12500。这也开箱即用。
例如:
CREATE TABLE t (
id serial PRIMARY KEY
, amount int8 NOT NULL
-- ...
);
data := []byte(`{"amount": 12500}`)
var obj struct {
Amount int64 `json:"amount"`
}
if err := json.Unmarshal(data, &obj); err != nil {
panic(err)
}
_, err := db.Exec(`INSERT INTO t (amount) VALUES ($1)`, obj.Amount)
如果您想使用pgtype.Numeric来存储和检索数据库中的金额,那么您将不得不做一些额外的工作,因为pgtype.Numeric不知道如何编码/解码 JSON 125.00/"125.00"值。
您可以做的一件事是声明一个自定义结构类型,让它嵌入该pgtype.Numeric类型,然后让自定义结构类型实现json.Marshaler和json.Unmarshaler接口。
例如:
CREATE TABLE t (
id serial PRIMARY KEY
, amount numeric(15,4) NOT NULL
-- ...
);
type MyNumeric struct {
pgtype.Numeric
}
func (n *MyNumeric) UnmarshalJSON(data []byte) error {
var s json.Number
if err := json.Unmarshal(data, &s); err != nil {
return err
}
return n.Numeric.Set(s.String())
}
func (n MyNumeric) MarshalJSON() ([]byte, error) {
var f float64
if err := n.Numeric.AssignTo(&f); err != nil {
return nil, err
}
return []byte(strconv.FormatFloat(f, 'f', -1, 64)), nil
}
data := []byte(`{"amount": 125.00}`)
var obj struct {
Amount MyNumeric `json:"amount"`
}
if err := json.Unmarshal(data, &obj); err != nil {
panic(err)
}
_, err := db.Exec(`INSERT INTO t (amount) VALUES ($1)`, obj.Amount)
- 1 回答
- 0 关注
- 86 浏览
添加回答
举报