我有一个 struct Person,它有一个 uint
类型的字段 AccessMode。在Postgres数据库中,AccessMode的数据类型是char(8)
。
我为 AccessMode 编写了一个自定义扫描函数,它实现了扫描仪接口(interface)。
在 Scan 函数中,它作为 ASCII 字符串的 uint8
slice 表示形式接收。
当数据库中 AccessMode 的数据类型更改为 varchar(8)
时,它会在 scan 函数中作为 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 形式接收?
最佳答案
这取决于您使用的驱动程序,为避免此类问题,您需要查阅驱动程序的文档。例如github.com/lib/pq
驱动程序在其 documentation 中提供了有关数据类型的部分。 .
- 整数类型smallint、integer 和bigint 以int64 形式返回
- 浮点类型实数和 double 以 float64 形式返回
- 字符类型 char、varchar 和 text 以字符串形式返回
- 时间类型 date、time、timetz、timestamp 和 timestamptz 是 以时间形式返回。时间
- bool 类型返回为 bool
- bytea 类型返回为 []byte
您会在上面注意到 lib/pq
声称将 char
类型的值作为 string
返回,这是正确的,然而,它可能看起来好像并非如此。我的意思是,在 postgres 中,有 char
类型,然后有 "char"
类型,以及上面的 lib/pq
指的是后者。
如果可能,您应该避免使用 char
和 varchar
,而使用 text
。
char什么时候是char?
当您将列声明为 char
或 char(n)
类型时,该列的实际类型将为 bpchar
(空白填充,固定长度字符类型),它不由 lib/pq
处理(尽管可能应该如此)。
当您将列声明为 "char"
类型时,该列的实际类型将为 "char"
(单字节字符类型供内部使用),它由 lib/pq
处理并以 string
形式返回。
- Why char datatype is converted to bpchar automatically?
- https://www.postgresql.org/docs/current/datatype-character.html
为了在这种特定情况下保护自己,您可以使用类型开关。
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")
}
关于database - 在Go中,扫描数据库的char和varchar数据类型有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61744776/