You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言使用db.Exec传递变量到MySQL创建表时出错

问题原因与解决方案

错误原因

Go的database/sql包及MySQL驱动中的?占位符仅用于替换SQL语句中的值参数(如INSERT、SELECT语句里的字段值),不能用来替换表名、列名这类SQL标识符。

当你尝试用?传递表名时,驱动会自动给参数加上单引号,最终生成的SQL语句会变成:

CREATE TABLE 'dokimi03' (id bigint(20) NOT NULL AUTO_INCREMENT, ...)

而MySQL的语法中,表名不需要用单引号包裹(特殊场景需用反引号),这就直接导致了语法错误。

解决方法

需要通过字符串拼接生成包含表名的SQL语句,但必须严格校验表名的合法性以避免SQL注入风险:

示例代码

import (
    "fmt"
    "log"
    "strings"
)

func main() {
    pinakas := "dokimi03"
    
    // 校验表名:仅允许字母、数字、下划线,可根据需求调整规则
    validChars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
    if strings.Trim(pinakas, validChars) != "" {
        log.Println("非法表名,仅允许字母、数字、下划线")
        return
    }

    // 拼接SQL语句,若表名含特殊字符/关键字,需用反引号包裹:`%s`
    crTable := fmt.Sprintf(`CREATE TABLE %s (
        id bigint(20) NOT NULL AUTO_INCREMENT,
        username varchar(100) NOT NULL,
        password varchar(100) NOT NULL,
        email varchar(100) NOT NULL,
        PRIMARY KEY (id)
    );`, pinakas)

    _, errCreate := db.Exec(crTable)
    if errCreate != nil {
        log.Println(errCreate)
    }
}

关键注意事项

  • 若表名包含特殊字符或MySQL关键字,需用反引号包裹表名,比如fmt.Sprintf("CREATE TABLE %s ...", pinakas)。
  • 绝对不能直接拼接未校验的用户输入作为表名,否则会引发严重的SQL注入漏洞。

内容的提问来源于stack exchange,提问作者Krackout

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 01:25:36