Задать вопрос
vanesxl
@vanesxl

Почему неправильно заполняется слайс?

Здравствуйте,
пытаюсь написать функцию, которая будет сохранять результат из БД в двумерный слайс. Пример взял тут
Вроде все работает, но почему то в двумерном слайсе дублируется последняя строка из запроса. Вот код:
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) // тут должны содержать все строки ответа, но почему то дублируется последняя
}

Что я делаю не так?
  • Вопрос задан
  • 93 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
vanesxl
@vanesxl Автор вопроса
Реализовал это так:
/*
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
}

Не ругайте сильно, я только начал изучать golang, но может кому то пригодится.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы