【发布时间】:2021-12-30 14:34:26
【问题描述】:
用户可以根据许多不同的标准请求产品价格,这将导致它可能访问表中的不同列。我正在遍历请求的产品并构建一堆查询,但遇到了一些麻烦。
逐个运行它们并组合结果比合并它们需要更长的时间。所以我尝试构建如下查询,它可以工作且速度很快,但现在很容易被注入。
没有联盟有没有更好的方法来做到这一点?或者有没有一种简单的方法可以像这样对动态查询进行参数化?
var fullQuery string
var counter int
for i, d:= range dataMap{
if counter != 0 {
fullQuery = fullQuery + " UNION "
}
var records string
for _, p := range d{
records = records + `'` + string(p) + `',`
}
recordLength:= len(records)
if recordLength> 0 && records [recordLength-1] == ',' {
records = records[:recordLength-1]
}
counter++
fullQuery = fullQuery + fmt.Sprintf(`
SELECT
price_`+fmt.Sprint(p.type)+` as price,
FROM products
WHERE products.id in (%s) and products.store= %s
`, records, p.store)
}
err := sqlx.Select(db, &dataStruct, fullQuery)
所以,在某些情况下,我可能会有以下查询:
SELECT
price_`+fmt.Sprint(p.type)+` as price,
FROM products
WHERE products.id in (%s) and products.store= %s
在其他情况下(取决于请求),我可能会有这样的情况:
SELECT
price_`+fmt.Sprint(p.type)+` as price,
FROM products
WHERE products.id in ('testid1', 'testid2') and products.store= 2
UNION
SELECT
price_`+fmt.Sprint(p.type)+` as price,
FROM products
WHERE products.id in ('testid3', 'testid4') and products.store= 1
如果我确定查询是什么,我只会使用 $1、$2 等,但我认为我不能在这里,因为我不知道会有多少参数并且它们都需要与众不同。
【问题讨论】:
-
这真的是一个关于如何使用
github.com/jmoiron/sqlx包(在你的问题中有一点点了解这个事实)和/或(一些未命名的)用于 Go 的 PostgreSQL 驱动程序(基于在问题标签上)?请更具体。 -
您不能在 SQL 中参数化列名。但是无论如何,列名更容易在后端代码中清理,因为所有名称都是预先知道的。它们没有像真实值这样的动态值。因此,您可以制作具有已知有效列名的地图,并查看用户输入是否在该地图中。如果它在地图中,您知道它是有效的并且不会造成任何伤害,因为只允许选择一小部分预定义值(列名)。
-
或者你尝试像这样stackoverflow.com/a/30120527/9208887。所以我说你不能参数化列名的说法并不完全正确。我不确定包含多个这样的列名有多容易。
-
@TheFool 澄清一下,我不是试图参数化列名,而是产品 ID 和商店值。 (%s 替换)。我会用更多信息更新最初的问题。
-
您肯定是在参数化列名。或者你会怎么称呼这个
SELECT price_+fmt.Sprint(p.type)+?如果你没有正确清理 p.type,那么你就有一个潜在的注入漏洞。
标签: postgresql go prepared-statement psql