Golang中单引号导致程序崩溃的问题探讨
Golang中单引号导致程序崩溃的问题探讨 我有一个插入例程,它不接受插入文本中的单引号:
single'quote
查询语句:
INSERT INTO posts (post_subject,post_desc,post_type,post_status) VALUES ('single'quote','test',0,0) RETURNING post_id
Go 代码:
func Insert(query string) int {
id := 0
err := db.QueryRow(query).Scan(&id)
if err != nil {
log.Fatal(err)
}
return id
}
这会导致 Go 崩溃,我收到如下错误信息:
pq: syntax error at or near "quote"
我的问题是,除了对每个字段都使用“replaceall”之外,还有其他方法吗?有时你确实希望在文本中使用单引号。是否有“允许单引号”的全局设置?我知道可以使用反引号(`),但难道没有其他方法吗?
更多关于Golang中单引号导致程序崩溃的问题探讨的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你是如何构建 INSERT 字符串的?single'quote 是你用来构建 SQL 的某个字符串的值吗?
更多关于Golang中单引号导致程序崩溃的问题探讨的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个字符串,没错。但你如何构建它呢?就目前而言,这不是有效的 SQL。
请查看我上面更新的答案。
lutzhorn:
DB.Exec
我需要一个返回值吗?使用 db.Exec 可以实现吗?
DB.QueryRow 支持占位符:
row := db.QueryRow("INSERT INTO foo (col) VALUES ($1)", "single'quote")
lutzhorn:
你是如何构建
INSERT字符串的?
INSERT INTO posts (post_subject,post_desc,post_type,post_status) VALUES ('single'quote','test',0,0) RETURNING post_id
lutzhorn:
但是,你如何构建它呢?
你为我指明了正确的方向。现在这个方法可以工作了。谢谢你!
query := "INSERT INTO posts (post_subject,post_desc,post_type,post_status)
VALUES ($1, $2, 0, 0)
RETURNING post_id"
subject := r.FormValue("subject")
desc := r.FormValue("desc")
id := Insert(query, subject, desc)
查询函数:
func Insert(query string, subject string, desc string) int {
id := 0
err := db.QueryRow(query, subject, desc).Scan(&id)
if err != nil {
log.Fatal(err)
}
return id
}
在Go中处理SQL查询时,单引号导致语法错误是因为没有正确进行参数化查询。直接拼接SQL字符串会导致SQL注入漏洞和这类语法问题。正确的方法是使用参数化查询。
以下是修正后的代码示例:
func InsertPost(subject, desc string, postType, status int) (int, error) {
var id int
query := `INSERT INTO posts (post_subject, post_desc, post_type, post_status)
VALUES ($1, $2, $3, $4) RETURNING post_id`
err := db.QueryRow(query, subject, desc, postType, status).Scan(&id)
if err != nil {
return 0, err
}
return id, nil
}
// 使用示例
func main() {
// 包含单引号的文本
subject := "single'quote"
desc := "test"
id, err := InsertPost(subject, desc, 0, 0)
if err != nil {
log.Fatal(err)
}
fmt.Printf("插入成功,ID: %d\n", id)
}
对于更复杂的场景,可以使用命名参数(如果数据库驱动支持):
import (
"database/sql"
_ "github.com/lib/pq"
"github.com/jmoiron/sqlx"
)
func InsertPostNamed(subject, desc string, postType, status int) (int, error) {
var id int
query := `INSERT INTO posts (post_subject, post_desc, post_type, post_status)
VALUES (:subject, :desc, :type, :status) RETURNING post_id`
// 使用sqlx进行命名参数查询
dbx := sqlx.NewDb(db, "postgres")
rows, err := dbx.NamedQuery(query, map[string]interface{}{
"subject": subject,
"desc": desc,
"type": postType,
"status": status,
})
if err != nil {
return 0, err
}
defer rows.Close()
if rows.Next() {
err = rows.Scan(&id)
}
return id, err
}
对于批量插入,可以使用预处理语句:
func BatchInsertPosts(posts []Post) error {
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
stmt, err := tx.Prepare(`INSERT INTO posts (post_subject, post_desc) VALUES ($1, $2)`)
if err != nil {
return err
}
defer stmt.Close()
for _, post := range posts {
_, err = stmt.Exec(post.Subject, post.Desc)
if err != nil {
return err
}
}
return tx.Commit()
}
参数化查询会自动处理特殊字符的转义,包括单引号,同时防止SQL注入攻击。这是处理SQL查询中特殊字符的标准做法。

