Reputation: 3680
In Postgres in Go, how can I make query parameters optional?
In this example status
is an optional condition. If no status
is passed all rows from table records will be fetched.
How to make query parameter &d.Status
an optional
type QueryParams struct {
Status string `json:"status"`
}
func (r repo) GetRecords(d *QueryParams) ([]*Records, error) {
statusQuery := ""
if d.Status != "" {
statusQuery = " where status = $1 "
}
query := "select id, title, status from records " + statusQuery
rows, err := r.db.Query(query, &d.Status)
}
Upvotes: 6
Views: 2829
Reputation: 434606
Query
is variadic so you could build an []interface{}
to hold the arguments:
args := []interface{}{}
and then to conditionally build the argument list:
if d.Status != "" {
statusQuery = " where status = $1 "
args = append(args, &d.Status)
}
When you run the query, expand the arguments using ...
:
rows, err := r.db.Query(query, args...)
Upvotes: 5
Reputation: 520928
You may use a flexible WHERE
clause, e.g.
SELECT id, title, status
FROM records
WHERE status = $1 OR $1 IS NULL;
The logic here is that if you provide a value for $1
, it must match the status in order for a record to be returned. Otherwise, if $1
be left out (i.e. is NULL
), then all records would be returned.
Note that to make this work from Go with the Postgres driver, you may need to do some extra massaging. I would try, at a first attempt, this:
statusQuery = "where status = $1 or $1::text is null"
query := "select id, title, status from records " + statusQuery
rows, err := r.db.Query(query, &d.Status)
Sometimes the driver can't figure out the type of the bound parameter $1
. By explicitly casting it to text
, the statement can be made to work.
Upvotes: 0