Reputation: 2393
Consider the db.Exec statement,
db.Exec("INSERT INTO $1 values($2,$3,to_timestamp($4),var1,var2,var3,var4)
^^ works however if I want to do something like
db.Exec("INSERT INTO table_name_$1 values($2,$3,to_timestamp($4),var1,var2,var3,var4)
It doesn't work, $1 gets appended to the table name instead of the values of $1, how do I add it to the query ?
Upvotes: 2
Views: 3387
Reputation: 48475
Since you say the first example works, one solution is to pass in the full table name as a parameter, doing the string concatenation beforehand:
db.Exec("INSERT INTO $1 values($2,$3)", "table_name_"+tbl, "this", "that")
You could also format the string manually with fmt.Sprintf
and %s
, as suggested in the comments.
I am a little surprised that your first example works, as this is not valid syntax in Postgres. If you create a prepared statement with the table name as a parameter, it returns a syntax error:
# 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);
Whereas the second example you gave also appends $1
to the name of the table, so the library is behaving correctly:
# 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);
So in your first example the library might be acting in your favor, but this is probably not something you should rely on too heavily.
The safest long-term solution is probably to use fmt.Sprintf
, with the necessary escaping, to format the table name, and then use that in the Exec
call:
sql := fmt.Sprintf(`INSERT INTO table_name_%s values($1,$2,to_timestamp($3))`, tbl)
db.Exec(sql, params...)
Upvotes: 3