How to escape back ticks
GoGo Problem Overview
MySQL requires tables that shadow reserved words to be back ticked. I have a table Role which is a reserved word, but I have already put my query in back ticks so I can write it over multiple lines (this is a toy query, large ones will not fit on one line).
How do I escape the back ticks?
Here is my code:
dbmap := db.InitDb()
var roles []entities.Role
query :=
` << Difficult to see with SO's code editor widget, but here is a back tick
SELECT *
FROM `Role` <<< Needs escaping
` << Difficult to see, but here is a back tick
_, err := dbmap.Select(&roles, query, nil)
if err != nil {
panic(err)
}
fmt.Println(roles)
Go Solutions
Solution 1 - Go
You cannot escape backticks inside backticks, but you can do:
dbmap := db.InitDb()
var roles []entities.Role
query := `
SELECT *
FROM ` + "`Role`"
_, err := dbmap.Select(&roles, query, nil)
if err != nil {
panic(err)
}
fmt.Println(roles)
Solution 2 - Go
If your query is long, it might be worth putting in a text file and reading it in, that will keep your code more concise and organized, and also avoid the backtick quoting issue entirely.
Solution 3 - Go
You can use .
prefix:
query := `
SELECT *
FROM .Role
`
Solution 4 - Go
I just used a placeholder (like the unicode ”
or basically anything which won't appear anywhere else in the query) instead of the backticks and replaced them afterwards:
strings.ReplaceAll(`CREATE TABLE ”mydatabase”.”mytable” (
”id” binary(16),
”sname” varchar(45),
PRIMARY KEY(”id”)
)`, "”", "`")
(Thanks to Andrey Tarantsov for proposing ”
as a placeholder.)
Solution 5 - Go
You can try writing queries like this:
query :=fmt.Sprintf("SELECT * FROM `Role`")
You can compare the outputs:
import "fmt"
func main() {
query :=fmt.Sprintf("SELECT * FROM `Role`")
fmt.Println(query)
fmt.Println( `SELECT * FROM ` + "`Role`") }
Solution 6 - Go
Use notepad++ on your plain text and replace (search and) replace
`
with
`+"`"+`
Solution 7 - Go
If you are using Go Templates you can pass the backtick in as a parameter:
package main
import (
"fmt"
"text/template"
"bytes"
)
func main() {
template,_ := template.New( "greeting").Parse(`Hello {{ .BT }}{{ .FirstName }}{{ .BT }}`)
data := struct {
FirstName string
BT string
}{
FirstName:"bob",
BT:"`", // <---- Here!
}
var buf bytes.Buffer
_ = template.Execute(&buf, data)
fmt.Print(buf.String())
}
gives:
Hello `bob`