sql - Golang 的 SQL 包是否无法进行即席/探索性查询?

标签 sql database go

根据文档,在 Go 中从数据库中获取数据的唯一方法似乎是使用 Rows.Scan(),这意味着您必须在编译时知道所有列的计数和类型。

我错过了什么吗?您应该如何支持临时查询?或者甚至从将来可能更改的表中提取所有列?

最佳答案

sql.Rows 类型有一个Columns 方法,该方法将为您提供结果列名称的列表。这可用于确定未知查询的列数。

Scan 方法的文档中,它说:

If an argument has type *[]byte, Scan saves in that argument a copy of the corresponding data. The copy is owned by the caller and can be modified and held indefinitely. The copy can be avoided by using an argument of type *RawBytes instead; see the documentation for RawBytes for restrictions on its use.

If an argument has type *interface{}, Scan copies the value provided by the underlying driver without conversion. If the value is of type []byte, a copy is made and the caller owns the result.

因此,我们还支持在不知道其类型时扫描列值:无论是原始形式还是 Go 类型。

将这两者放在一起,您可以使用 ... syntax to call variadic functions 执行以下操作:

columnNames, err := rows.Columns()
if err != nil {
    log.Fatalln(err) // or whatever error handling is appropriate
}
columns := make([]interface{}, len(columnNames))
columnPointers := make([]interface{}, len(columnNames))
for i := 0; i < len(columnNames); i++ {
    columnPointers[i] = &columns[i]
}
if err := rows.Scan(columnPointers...); err != nil {
    log.Fatalln(err)
}

现在 columns slice 应该包含当前结果行的所有列值的解码版本。

如果您对表有额外的了解(例如,预期类型,或提前知道列数),您可能可以稍微简化逻辑。

关于sql - Golang 的 SQL 包是否无法进行即席/探索性查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23507531/

相关文章:

sql - oracle sql select 与员工

java - 一个数据库单元格中的多个日期

PHP - 保留随机查询结果 24 小时

SQL 将 varchar2 转换为数字

go - 找不到包 "google/protobuf"

c# - 从 SQL Server 存储过程返回 bigint

java - hibernate 或数据库 : Which is better place for foreign key constraints?

database - 如何找到 DB2 (luw) 数据库的大小?

go - 在Go中编译Google-Fhir Proto文件时出错

go - 时区字符串格式