根据文档,在 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/