英文:
Golang database/sql.DB.QueryRow with multiple args
问题
我想执行类似这样的查询(使用MySQL):
select * from user where id = 5
示例1:这将返回err = sql.ErrNoRows
:
err := db.QueryRow("select * from user where ? = ?", f, v).Scan(&user.Id, etc...)
示例2:由于上述方法不起作用,我正在以这种方式执行,虽然它能工作,但感觉不对:
err := db.QueryRow("select * from user where "+f+" = ?", v).Scan(&user.Id, etc...)
示例1有什么问题?示例2是一种可接受的方法吗?
编辑
从评论中的链接中,我可以以第三种方式执行。
示例3:
q := fmt.Sprintf("select * from user where %s = ?", f)
err := db.QueryRow(q, v).Scan(&user.Id, etc...)
英文:
I want to execute a query something like this (using MySql):
select * from user where id = 5
Ex 1. This returns err = sql.ErrNoRows
:
err := db.QueryRow("select * from user where ? = ?", f, v).Scan(&user.Id, etc...)
Ex 2. Since the above doesn't work, I am doing it this way, which works but doesn't feel right:
err := db.QueryRow("select * from user where "+f+" = ?", v).Scan(&user.Id, etc...)
What is wrong in Ex. 1? Is Ex 2. an acceptable way to do this?
EDIT
From the link in the comments I can do it a third way.
Ex 3:
q := fmt.Sprintf("select * from user where %s = ?", f)
err := db.QueryRow(q, v).Scan(&user.Id, etc...)
答案1
得分: 1
你需要直接在 SQL 查询中提供列名。'?' 符号是你在 SQL 字符串之后提供的值的占位符。
你的 Ex3. 是正确的,但不是一个好的解决方案,因为它容易受到 SQL 注入攻击。
如果你需要一个轻量级的解决方案,你可以为每个表创建一个包含已知列名的映射,例如:userColumns := map[string]bool {"id": true, ...}
,然后使用以下检查:
if userColumns[f] {
...你可以在 SQL 中使用 f...
} else {
...提供的值不是已知列之一,这是一个错误...
}
英文:
You need to provide column names directly in sql query. '?' sign is a placeholder for values you provide after sql string.
Your Ex3. is correct, but it is not a good solution, because it is open for SQL-injection attacks.
If you need a lightweight solution you can create a map with known column names for each table like: userColumns := map[string]bool {"id": true, ...}
and then just use next check:
if userColumns[f] {
...you able to use f in sql...
} else {
...provided value is not one of known columns, it is an error...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论