title: read "SELECT *" columns into []string in go
body: <p>I want to write a Go program to dump rows 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> &quot;fills&quot; 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 &quot;right&quot; 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>