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 關注
- 118 瀏覽
添加回答
舉報