在Go中,数据库的char和varchar数据类型的扫描方式有区别吗?

问题描述 投票:0回答:1

我有一个结构体Person,它的字段AccessMode类型为 uint. 在 Postgres 数据库中,AccessMode 的数据类型是 char(8).我为AccessMode写了一个自定义的Scan函数,它实现了Scanner Interface.在Scan函数中,它是作为一个函数接收的。uint8 ASCII字符串的分片表示。当AccessMode的数据类型变更为 varchar(8) 在数据库中,它是作为一个 string 在扫描功能中。以下是代码

type Access uint

type Person struct {
   AccessMode Access
}

func (a *Access) Scan(val interface{}) error {
  if bb, ok := val.([]byte); ok {                                                                                                             
    return a.UnmarshalText(bb)
  }
  return errors.New("scan failed: data is not a byte slice")
}

为什么在扫描函数中,如果是varchar,则以字符串的形式接收,如果是char数据类型,则以uint slice的形式接收?

database postgresql go
1个回答
1
投票

这取决于你使用的驱动程序,为了避免出现这样的问题,你需要查阅驱动程序的文档。例如 github.com/lib/pq 驱动程序在其 文件.

  • 整数类型smallint、integer和bigint被返回为int64。
  • 浮点类型的实数和双精度返回为float64。
  • 字符类型为char、varchar和text,以字符串形式返回。
  • 时间类型date, time, timetz, timestamp, and timestamptz以time.Time的形式返回。
  • 布尔类型被返回为bool。
  • 返回的字节a类型为[]byte。

你会注意到,在上面的 lib/pq 声称返回的值为 char 类型为 string虽说是这样,但是 似乎 像不像。我的意思是说,在postgres中,有一个叫 char 类型,然后是 "char" 型,以及 lib/pq 上文中的是指后者。

如果可能,你应该避免使用 charvarchar 而改用 text.

什么时候char是char?

当你声明一个列的类型为 charchar(n),该列的实际类型将是 bpchar (空白填充、固定长度的字符类型),这不是由 lib/pq (尽管它可能应该是)。

当你声明一个列的类型为 "char",该列的实际类型将是 "char" 内用字型,这是由 lib/pq 并返回为 string.


为了在这种特殊情况下屏蔽自己,你可以使用类型开关。

func (a *Access) Scan(src interface{}) error {
    switch val := src.([]byte) {                                                                                                             
    case []byte:
        return a.UnmarshalText(val)
    case string:
        return a.UnmarshalText([]byte(val))
    }
    return errors.New("scan failed: data is not a byte slice")
}
© www.soinside.com 2019 - 2024. All rights reserved.