插入 postgresql 十进制字段失败,出现错误“无法将 {125.00} 转换为 Int2”

我对 golang 很陌生。我正在尝试使用网络应用程序 gin-gonic 插入到具有数字字段的 postgresql 表中。


postgres=# \d user_txns;

                       Table "public.user_txns"

   Column    |         Type          | Collation | Nullable | Default

-------------+-----------------------+-----------+----------+---------

 user_id     | character varying(15) |           | not null |

 txn_code    | smallint              |           | not null |

 description | character varying(64) |           | not null |

 txn_amount  | numeric(15,4)         |           | not null |

 txn_type    | smallint              |           | not null |

 voucher     | character varying(16) |           |          |

我正在使用 jackc pgxpool 插入到表中,如下所示。


109 ▏ sql := `INSERT INTO user_txns VALUES ($1,$2, $3, $4, $5)`

▎ 110 ▏ _, err = tx.Exec(context.Background(), sql,

▎ 111 ▏ ▏ ▏ ▏ ▏ ▏ claims["phone"],

▎ 112 ▏ ▏ ▏ ▏ ▏ ▏ recharge,

▎ 113 ▏ ▏ ▏ ▏ ▏ ▏ "User recharge",

▎ 114 ▏ ▏ ▏ ▏ ▏ ▏ recharge.Amount,

▎ 115 ▏ ▏ ▏ ▏ ▏ ▏ credit,

▎ 116 ▏ )

▎ 117 ▏ if err != nil {

▎ 118 ▏ ▏ c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})

▎ 119 ▏ ▏ return

▎ 120 ▏ },

有效负载是具有以下结构的 json 请求:


{

  "amount": 125.00 

}

我将请求解组为如下定义的结构。


type Recharge struct {

  Amount string `json:"amount" binding:"required"`

}

插入失败并出现错误


"msg": "无法将 {125} 转换为 Int2"


用于插入小数字段的正确 golang 数据类型是什么?


谢谢


LEATH
浏览 90回答 1
1回答

潇潇雨雨

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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go