Go语言单个数据库查询以处理多个参数

huangapple go评论88阅读模式
英文:

Go language single database query to address many parameters

问题

我正在构建一个 Rest API,格式为 query/{occupation}/{location}

现在,在 .go 文件中,我有以下代码:

position := params["occupation"]
loc := params["location"]
rows, err := db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1 AND location=$2`,
                       position, loc);

如果我们调用我的 API 时同时存在 occupation 和 location,这段代码运行得很好。
我希望它更加灵活,可以忽略一些参数,例如,我想调用 abc.com/query/dentist/NULL

那么我可以有以下代码:

if loc == nil && position == nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable);
} else if loc == nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1`, position);
} else if position = nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable WHERE location=$1`, loc);
} else {
    rows, err := db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1 AND location=$2`,
                       position, loc);
}

但是这种方法不可持续,因为我的 RestAPI 可能支持 10 个参数,而 if else 语句将会增长到 2^10。

我想知道是否可以只使用一个查询来处理所有情况。

这可能是一个简单的 SQL 问题,我只是无法解决它(我正在使用 postgres 数据库)。

英文:

I am building a Rest API, in the format of query/{occupation}/{location}

Now, in the .go file, I have

position := params["occupation"]
loc := params["location"]
rows, err := db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1 AND location=$2`,
                       position, loc);

This works great if we call my API with both occupation and location exist.
I want it to be more flexible so I can ignore some parameters, for example, I want to call abc.com/query/dentist/NULL.

Then I could have this code:

if loc == nil && position == nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable);
} else if loc == nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1`, position);
} else if position = nil {
    rows, err = db.Query(`SELECT occupation, location 
                       FROM myTable WHERE location=$1`, loc);
} else {
    rows, err := db.Query(`SELECT occupation, location 
                       FROM myTable WHERE occupation=$1 AND location=$2`,
                       position, loc);
}

But this is not sustainable since my RestAPI may support 10 parameters and the if else clauses would grow to 2^10.

I am wonder just using one query to address all cases.

This maybe a simple SQL question, I just cannot figure it out (I'm using postgres).

答案1

得分: 1

这是一个非常基本的变量检查,你不需要执行所有三个查询,例如:

var (
	rows     *sql.Rows
	err      error
	position = params["occupation"]
	loc      = params["location"]
)
switch {
case loc != "" && position != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE occupation=$1 AND location=$2'`, position, loc)
case loc != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE location=$1`, loc)
case position != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE occupation=$1`, position)
default:
	rows, err = db.Query(`SELECT occupation, location FROM myTable`)
}
if err != nil {
	panic(err)
}
英文:

It's really a basic variable checking, you don't need to do all 3 queries, for example :

var (
	rows     *sql.Rows
	err      error
	position = params["occupation"]
	loc      = params["location"]
)
switch {
case loc != "" && position != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE occupation=$1 AND location=$2'`, position, loc)
case loc != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE location=$1`, loc)
case position != "":
	rows, err = db.Query(`SELECT occupation, location FROM myTable WHERE occupation=$1`, position)
default:
	rows, err = db.Query(`SELECT occupation, location FROM myTable`)
}
if err != nil {
	panic(err)
}

答案2

得分: 0

也许你应该使用一些 ORM 来进行更好的设计。

这个链接可能会有所帮助:https://github.com/jinzhu/gorm#query-with-where-struct--map

或者你可以通过拼接 SQL 并添加绑定参数来编译 where 条件进行查询。但要注意防止 SQL 注入。

英文:

Maybe you should use some ORM for better design.

This should help: https://github.com/jinzhu/gorm#query-with-where-struct--map

Or you can compile the where condition by concatenating SQL and adding bind parameters to query. But watch out for SQL injection.

答案3

得分: 0

忽略一个参数,将其传递为 null 并更改查询为:

select occupation, location
from mytable
where
    (occupation = $1 or $1 is null)
    and
    (location = $2 or $2 is null)

这将与参数的数量成线性比例扩展。

英文:

To ignore a parameter pass it as null and change the query to :

select occupation, location
from mytable
where
    (occupation = $1 or $1 is null)
    and
    (location = $2 or $2 is null)

This will scale linearly with the number of parameters.

huangapple
  • 本文由 发表于 2014年6月8日 09:45:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/24102283.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定