我想編寫一個Go程序,使用SELECT *
將數據庫表中的行轉儲爲csv文件。將「SELECT *」列讀入[]中的字符串
轉到提供了優良sql和csv的API,但是csv
期望字符串數組,並根據它們的類型在Rows
的Scan
方法「填充」字段。 因爲我以前不知道表格,所以我不知道有多少列以及它們的類型是什麼。
這是我在Go的第一個程序,所以我掙扎了一下。
如何最好地將Rows
實例中的列讀入[]string
- 這是「正確」的方式嗎?
謝謝!
UPDATE
我仍與參數掙扎。這是我的代碼,現在我正在使用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
。
UPDATE 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
}
嘿,太棒了!我剛到達那裏,想發佈一個編輯。謝謝!這將是我的答案,我會upvote它,但我仍然有一個問題:我希望這是快速的,我想逃避字符串值並將nil轉換爲\ N。我如何最好地在我的代碼中包含轉換? – Arne
我的解決方案遠離水密。它要求值能夠存儲在一個「字符串」中。例如。如果你從數據庫中獲得一個NULL值,你將會有一個錯誤,因爲字符串不能是'nil'。我使用[]字節更新了答案並檢查了'nil'值。 – ANisus
您可能會考慮使用'sql.RawBytes'而不是'[] byte' –