Tôi muốn viết chương trình Go để kết xuất các hàng từ bảng cơ sở dữ liệu vào tệp csv bằng cách sử dụng SELECT *
.đọc các cột "SELECT *" vào chuỗi [] ở chế độ
Go cung cấp tuyệt vời sql và csv apis, nhưng csv
hy vọng mảng các chuỗi và Scan
phương pháp trong Rows
"lấp đầy" các lĩnh vực theo từng loại. Vì tôi không biết bảng trước, tôi không biết có bao nhiêu cột và loại của chúng là gì.
Đây là chương trình đầu tiên của tôi ở Go, vì vậy tôi đang phải vật lộn một chút.
Làm cách nào để đọc tốt nhất các cột từ một ví dụ Rows
thành một số []string
- và đó có phải là cách "đúng" không?
Cảm ơn!
CẬP NHẬT
tôi vẫn phải vật lộn với các thông số. Đây là mã của tôi, hiện tại tôi đang sử dụng panic
thay vì trả lại error
, nhưng tôi sẽ thay đổi điều đó sau. Trong thử nghiệm của tôi, tôi chuyển kết quả truy vấn và 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
}
Đối với điều này, tôi nhận được cannot use cols (type []string) as type []interface {} in function argument
(tại dòng writer.Write(cols)
.
sau đó tôi thử nghiệm
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)
}
dẫn đến panic: sql: Scan error on column index 0: destination not a pointer
.
UPDATE 2
Tôi đã độc lập đến giải pháp ANisus '. Đây là mã tôi đang sử dụng bây giờ.
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
}
Xin chào, tuyệt! Tôi vừa mới đến đó và muốn đăng nó trong một bản chỉnh sửa. Cảm ơn! Đó sẽ là câu trả lời của tôi và tôi sẽ upvote nó, nhưng tôi vẫn có một câu hỏi: Tôi muốn điều này được nhanh chóng và tôi muốn thoát khỏi chuỗi giá trị và chuyển đổi nil để \ N. Làm cách nào để bao gồm các chuyển đổi trong mã của tôi tốt nhất? – Arne
Giải pháp của tôi nằm cách xa nước. Nó yêu cầu các giá trị để có thể được lưu trữ trong một 'chuỗi'. Ví dụ. nếu bạn nhận được giá trị NULL từ db, bạn sẽ gặp lỗi vì chuỗi không thể là 'nil'. Tôi đã cập nhật câu trả lời bằng cách sử dụng byte [] và kiểm tra các giá trị 'nil'. – ANisus
Bạn có thể xem xét sử dụng 'sql.RawBytes' thay vì' [] byte' –