Note that there are some explanatory texts on larger screens.

plurals
  1. POread "SELECT *" columns into []string in go
    text
    copied!<p>I want to write a Go program to dump rows from from a database table into a csv file using <code>SELECT *</code>.</p> <p>Go provides the excellent <a href="http://golang.org/pkg/database/sql" rel="noreferrer">sql</a> and <a href="http://golang.org/pkg/encoding/csv/" rel="noreferrer">csv</a> apis, but <code>csv</code> expects arrays of strings and the <code>Scan</code> method in <code>Rows</code> "fills" fields according to their types. As I don't know the table before, I have no idea how many columns there are and what their types are.</p> <p>It's my first program in Go, so I'm struggling a little.</p> <p>How do I best read the columns from a <code>Rows</code> instance into a <code>[]string</code> - and is that the "right" way?</p> <p>Thanks!</p> <p><strong>UPDATE</strong></p> <p>I'm still struggling with the parameters. This is my code, for now I'm using <code>panic</code> instead of returning an <code>error</code>, but I'm going to change that later. In my test, I'm passing the query result and <code>os.Stdout</code>.</p> <pre><code>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 } </code></pre> <p>For this, I get <code>cannot use cols (type []string) as type []interface {} in function argument</code> (at the <code>writer.Write(cols)</code> line.</p> <p>I then tested</p> <pre><code> 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) } </code></pre> <p>which lead to <code>panic: sql: Scan error on column index 0: destination not a pointer</code>.</p> <p><strong>UPDATE 2</strong></p> <p>I independently arrived at <a href="https://stackoverflow.com/users/694331/anisus">ANisus</a>' solution. This is the code I'm using now.</p> <pre><code>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] = &amp;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 } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload