V
V
Vanes Ri_Lax2019-07-10 14:33:36
go
Vanes Ri_Lax, 2019-07-10 14:33:36

Why is the slice filled incorrectly?

Hello,
I'm trying to write a function that will save the result from the database into a two-dimensional slice. I took an example here
It seems that everything works, but for some reason the last line from the request is duplicated in a two-dimensional slice. Here is the code:

package main

import (
  "database/sql"
  "fmt"

  _ "github.com/lib/pq"
  "domen.ru/config"
)

func main() {
  var out [][]string

  db, err := sql.Open("postgres", config.PostgresqlConfig)
  defer db.Close()

  if err != nil {
    fmt.Println("Failed to connect", err)
    return
  }

  rows, err := db.Query("SELECT id, closing_step_id FROM table1")
  if err != nil {
    fmt.Println("Failed to run query", err)
    return
  }

  cols, err := rows.Columns()
  if err != nil {
    fmt.Println("Failed to get columns", err)
    return
  }

  // Result is your slice string.
  rawResult := make([][]byte, len(cols))
  result := make([]string, len(cols))

  dest := make([]interface{}, len(cols)) // A temporary interface{} slice
  for i, _ := range rawResult {
    dest[i] = &rawResult[i] // Put pointers to each string in the interface slice
  }

  for rows.Next() {
    err = rows.Scan(dest...)
    if err != nil {
      fmt.Println("Failed to scan row", err)
      return
    }

    for i, raw := range rawResult {
      if raw == nil {
        result[i] = "\\N"
      } else {
        result[i] = string(raw)
      }

    }

    out = append(out, result) //тут добавляю слайс в слайс

    fmt.Println(result) // если тут выводить то будет массив из 2-х элементов [str1 str2]
  }
  fmt.Println(out) // тут должны содержать все строки ответа, но почему то дублируется последняя
}

What am I doing wrong?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
VaneS Ri_Lax, 2019-07-11
@vanesxl

Implemented it like this:

/*
ClientPostgres делает запросы к бд.
На вход запрос.
На выход слайс столбцов и строк.
*/
func ClientPostgres(reqSQL string) ([]string, [][]string) {

  var out [][]string

  db, err := sql.Open("postgres", config.PostgresqlConfig)
  defer db.Close()

  if err != nil {
    fmt.Println("Failed to connect", err)
    return nil, nil
  }

  rows, err := db.Query(reqSQL)
  if err != nil {
    fmt.Println("Failed to run query", err)
    return nil, nil
  }

  cols, err := rows.Columns()
  if err != nil {
    fmt.Println("Failed to get columns", err)
    return nil, nil
  }

  // Result is your slice string.
  rawResult := make([][]byte, len(cols))
  result := make([]string, len(cols))

  dest := make([]interface{}, len(cols)) // A temporary interface{} slice
  for i, _ := range rawResult {
    dest[i] = &rawResult[i] // Put pointers to each string in the interface slice
  }

  for rows.Next() {
    err = rows.Scan(dest...)
    if err != nil {
      fmt.Println("Failed to scan row", err)
      return nil, nil
    }

    for i, raw := range rawResult {
      if raw == nil {
        result[i] = "\\N"
      } else {
        result[i] = string(raw)
      }
    }

    rowitem := make([]string, len(cols))
    for i := 0; i < len(cols); i++ {
      rowitem[i] = result[i]
    }
    out = append(out, rowitem)
  }
  return cols, out
}

Do not scold too much, I just started learning golang, but maybe it will come in handy for someone.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question