考虑db.Exec语句
db.Exec(“INSERT INTO $ 1 values($ 2,$ 3,to_timestamp($ 4),var1,var2,var3,var4)
^^但是如果我想做像
那样的话db.Exec(“INSERT INTO table_name_ $ 1 values($ 2,$ 3,to_timestamp($ 4),var1,var2,var3,var4)
它不起作用,$ 1会附加到表名而不是$ 1的值,我该如何将它添加到查询中?
答案 0 :(得分:2)
由于您说第一个示例有效,一种解决方案是将完整的表名作为参数传递,事先进行字符串连接:
db.Exec("INSERT INTO $1 values($2,$3)", "table_name_"+tbl, "this", "that")
您还可以使用fmt.Sprintf
和%s
手动格式化字符串,如评论中所示。
我有点惊讶你的第一个例子有效,因为这不是Postgres中的有效语法。如果使用表名作为参数创建预准备语句,则会返回语法错误:
# PREPARE fooplan (text, bool, numeric) AS
INSERT INTO $1 VALUES($2, $3);
ERROR: syntax error at or near "$1"
LINE 2: INSERT INTO $1 VALUES($2, $3);
而您提供的第二个示例也会将$1
附加到表的名称,因此库的行为正确:
# PREPARE fooplan (text, bool, numeric) AS
INSERT INTO table_name_$1 VALUES($2, $3);
ERROR: relation "table_name_$1" does not exist
LINE 2: INSERT INTO table_name_$1 VALUES($2, $3);
所以在你的第一个例子中,库可能对你有利,但这可能不是你应该过分依赖的东西。
最安全的长期解决方案可能是使用fmt.Sprintf
进行必要的转义,以格式化表名,然后在Exec
调用中使用它:
sql := fmt.Sprintf(`INSERT INTO table_name_%s values($1,$2,to_timestamp($3))`, tbl)
db.Exec(sql, params...)