我想编写一个 Go 程序来将数据库表中的行转储到 csv 文件中SELECT *
。
Go 提供了出色的sql和csv api,但csv
需要字符串数组和根据其类型“填充”字段Scan
中的方法。Rows
由于我以前不知道该表,因此我不知道有多少列以及它们的类型。
这是我在 Go 中的第一个程序,所以我有点挣扎。
我如何最好地将Rows
实例中的列读入[]string
- 这是“正确”的方式吗?
谢谢!
更新
我仍在为参数而苦苦挣扎。这是我的代码,现在我使用panic
而不是返回一个error
,但我稍后会更改它。在我的测试中,我传递了查询结果和os.Stdout
.
func dumpTable(rows *sql.Rows, out io.Writer) error {
colNames, err := rows.Columns()
if err != nil {
panic(err)
}
if rows.Next() {
writer := csv.NewWriter(out)
writer.Comma = '\t'
cols := make([]string, len(colNames))
processRow := func() {
err := rows.Scan(cols...)
if err != nil {
panic(err)
}
writer.Write(cols)
}
processRow()
for rows.Next() {
processRow()
}
writer.Flush()
}
return nil
}
为此,我得到cannot use cols (type []string) as type []interface {} in function argument
(writer.Write(cols)
在线。
然后我测试了
readCols := make([]interface{}, len(colNames))
writeCols := make([]string, len(colNames))
processRow := func() {
err := rows.Scan(readCols...)
if err != nil {
panic(err)
}
// ... CONVERSION?
writer.Write(writeCols)
}
这导致panic: sql: Scan error on column index 0: destination not a pointer
.
更新 2
我独立得出了ANisus的解决方案。这是我现在使用的代码。
func dumpTable(rows *sql.Rows, out io.Writer) error {
colNames, err := rows.Columns()
if err != nil {
panic(err)
}
writer := csv.NewWriter(out)
writer.Comma = '\t'
readCols := make([]interface{}, len(colNames))
writeCols := make([]string, len(colNames))
for i, _ := range writeCols {
readCols[i] = &writeCols[i]
}
for rows.Next() {
err := rows.Scan(readCols...)
if err != nil {
panic(err)
}
writer.Write(writeCols)
}
if err = rows.Err(); err != nil {
panic(err)
}
writer.Flush()
return nil
}