Как создать структуру для динамического c SQL запроса? - PullRequest
0 голосов
/ 24 февраля 2020

В моем приложении Golang я делаю SQL запрос к базе данных. Обычно в запросе SQL я указываю столбцы, которые я хочу получить из таблицы, и создаю структуру на ее основе. Вы можете увидеть пример рабочего кода ниже.

ВОПРОС :

Что мне делать, если я не знаю количество и название столбцов в таблице ? Например, я делаю запрос SQL как SELECT * from filters; вместо SELECT FILTER_ID, FILTER_NAME FROM filters;. Как мне создать структуру в этом случае?

var GetFilters = func(responseWriter http.ResponseWriter, request *http.Request) {
    rows, err := database.ClickHouse.Query("SELECT * FROM filters;"); if err != nil {
        fmt.Println(err)
        return
    }

    defer rows.Close()

    columns, err := rows.Columns(); if err != nil {
        fmt.Println(err)
        return
    }

    filters := make([]interface{}, len(columns))

    for i, _ := range columns {
        filters[i] = new(sql.RawBytes)
    }

    for rows.Next() {
        if err = rows.Scan(filters...); err != nil {
            fmt.Println(err)
            return
        }
    }

    utils.Response(responseWriter, http.StatusOK, filters)
}

Ответы [ 2 ]

0 голосов
/ 28 февраля 2020

Ну наконец-то я нашел решение. Как видно из приведенного ниже кода, сначала я делаю запрос SQL, в котором не указывается название столбцов. Затем я беру информацию о столбцах с помощью функции ColumnTypes(). Эта функция возвращает информацию о столбце, такую ​​как тип столбца, длина и значение NULL. Далее я узнаю название и тип столбцов, заполните интерфейс этими данными:

for i, column := range columns {
    object[column.Name()] = reflect.New(column.ScanType()).Interface()
    values[i] = object[column.Name()]
}

Полный код, который я использую, выглядит следующим образом:

var GetFilters = func(responseWriter http.ResponseWriter, request *http.Request) {
    rows, err := database.ClickHouse.Query("SELECT * FROM table_name;"); if err != nil {
        fmt.Println(err)
        return
    }

    defer rows.Close()

    var objects []map[string]interface{}

    for rows.Next() {
        columns, err := rows.ColumnTypes(); if err != nil {
            fmt.Println(err)
            return
        }

        values := make([]interface{}, len(columns))

        object := map[string]interface{}{}

        for i, column := range columns {
            object[column.Name()] = reflect.New(column.ScanType()).Interface()
            values[i] = object[column.Name()]
        }

        if err = rows.Scan(values...); err != nil {
            fmt.Println(err)
            return
        }

        objects = append(objects, object)
    }

    utils.Response(responseWriter, http.StatusOK, objects)
}
0 голосов
/ 24 февраля 2020

Используйте таблицу USER_TAB_COLUMNS, чтобы получить список столбцов в запросе исполняемой таблицы, сохранить его в виде массива или коллекции. позже выполните запрос и просканируйте столбцы, которые вы уже знаете из предыдущего запроса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...