Извлечение всех записей из Postgres с использованием веб-формы Golang, когда фильтр не применен, т.е. пустое предложение «Где» - PullRequest
0 голосов
/ 17 апреля 2020

У меня есть Golang функция для извлечения всех записей из базы данных Postgres, эта функция просто использует:

SELECT * from stock_transactions Я хочу применить фильтр к этой функции для извлечения записей с некоторыми условиями Короче говоря, я хочу использовать:

SELECT * from stock_transactions WHERE symbol = $symb

Проблема состоит в том, чтобы обработать случай, когда если $symb = null запрос должен действовать как SELECT * from stock_transactions. Я могу написать предложение if-else для того же самого, но если количество параметров больше 2, это может быть грязно. Есть ли лучший способ справиться с этим?

Моя функция:

func showstocks (w http.ResponseWriter, r *http.Request){

    var err error

if r.Method != "GET" {
    http.Error(w, http.StatusText(405), http.StatusMethodNotAllowed)
    return
}

rows, err := db.Query("SELECT * FROM stock_transaction ORDER BY id DESC")
if err != nil {
    http.Error(w, http.StatusText(500), 500)
    return
}
defer rows.Close()

sks := make([]stockdata, 0)


for rows.Next() {
    sk := stockdata{}
    err := rows.Scan(&sk.Sname, &sk.Ttype, &sk.Uprice, &sk.Qty, &sk.Bfee, &sk.Ddate) 
    if err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
    sks = append(sks, sk)
}
if err = rows.Err(); err != nil {
    http.Error(w, http.StatusText(500), 500)
    return
}

tpl.ExecuteTemplate(w, "dashboard.gohtml", sks)

}

Ответы [ 2 ]

0 голосов
/ 18 апреля 2020

Вы можете использовать трюк (stock_symbol = $1 OR $1 IS NULL), как вы уже видели, что удобно с точки зрения программирования. Однако это часто может привести к неэффективным запросам, так как планировщик запросов может быть недостаточно умен, чтобы правильно их оптимизировать. Возможно, было бы лучше написать некоторый код, который удаляет тавтологические фразы, а также удаляет соответствующие переменные связывания, а не передает каждую из них в базу данных. Это немного грязно, но должно быть заключено в функцию, а не переписываться каждый раз.

0 голосов
/ 17 апреля 2020

// Предложено @mkopriva. Пробовал и проверял.

основной пакет

import ("fmt")

fun c main () {// ...

// use interface{} because string types cannot be nil
var stock_symbol interface{} // the "zero-value of interface types is nil, so stock_symbol here is nil

// if empty then stock_symbol will be left as nil
if val := r.FormValue("stock_symbol"); len(val) > 0 {
    stock_symbol = val // set to the provided value
}

// ...

// now stock_symbol is either the provided string value or nil
db.Query("SELECT ... WHERE (stock_symbol = $1 OR $1 IS NULL)", stock_symbol)

}

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