Go 如何为pq驱动程序准备带有动态表名的INSERT语句

Go 如何为pq驱动程序准备带有动态表名的INSERT语句,go,pq,Go,Pq,如何为pq postgres驱动程序准备的INSERT语句使用动态表名?目前,我有一个带有id SERIAL和values TEXT列的测试表,但该语句失败: stmt, err := db.Prepare("INSERT INTO $1(values) VALUES($2);") if err != nil { log.Fatal(err) } 这是失败的: pq:在“$1”处或附近出现语法错误 如果我只能对值使用占位符,而不能对表名使用占位符,有没有办法在这里使用Sprintf?表

如何为pq postgres驱动程序准备的
INSERT
语句使用动态表名?目前,我有一个带有
id SERIAL
values TEXT
列的测试表,但该语句失败:

stmt, err := db.Prepare("INSERT INTO $1(values) VALUES($2);")
if err != nil {
    log.Fatal(err)
}
这是失败的:

pq:在“$1”处或附近出现语法错误


如果我只能对值使用占位符,而不能对表名使用占位符,有没有办法在这里使用
Sprintf
?表名包含来自用户输入的
字符串,尽管我可以对其进行清理,但与让Postgres在准备好的语句上返回错误相比,插入速度会慢一些。

要替换表名变量,go sql包还没有提供标准接口()

您可能可以使用特定于数据库驱动程序的报价函数,例如:


另请参见示例。

从用户输入中获取表名,即使您使用准备好的语句拒绝SQL注入,也是非常危险的—它们可能会命中任何表。如果必须执行此操作,请使用
Sprintf
,但请确保根据数据库文档将表名清理为表名中允许的字符。@Adrian注意到。表名实际上是由一个强大的散列函数组成的,预先计算并存储在
映射
@AndreaM16中。问题特别是“这里有没有办法使用Sprintf”。您不能使用占位符作为标识符(例如表名和列名)。标识符存在于与值不同的级别(就像Go中的变量名存在于与值不同的级别,如
6
)。将它们列为白名单并引用(由于数据库界面中没有“quote identifier”功能,因此手动引用),然后使用
Sprintf