使用Go语言pq库操作PostgreSQL时插入语句报逗号附近语法错误
解决PostgreSQL INSERT语句的语法错误问题
哦,这个问题我之前踩过坑!核心原因很简单:Go的PostgreSQL驱动(比如常用的pq包)不支持用?作为参数占位符,它要求用$1、$2这种带位置编号的占位符。你在PostgreSQL查询工具里用?能正常执行,大概率是工具自动帮你做了转译,但Go驱动可不会干这个事,所以直接用?就会触发syntax error at or near ","的错误。
给你几个具体的解决思路和修改建议:
- 替换占位符格式:把SQL语句里的所有
?换成对应的$1到$10(因为你一共有10个参数),每个占位符对应后面传入的参数顺序。 - 修正事务的使用:我注意到你代码里开启了事务
txn, err := db.Begin(),但后续却用db.Prepare来创建语句——这会绕开你开启的事务,所有操作不会在事务内执行。应该改用txn.Prepare来保证整个插入逻辑在事务上下文里。
修改后的完整代码示例:
txn, err := db.Begin() if err != nil { // 别忘了处理错误,比如log.Fatal(err)或者返回错误 } defer txn.Rollback() // 先注册回滚,确保后续出错时能回滚事务 // 用$N占位符替换原来的?,并且用txn.Prepare创建事务内的语句 stmt, err := txn.Prepare(`INSERT INTO advertiser_per_day (id,advertiser_name,additional,customer_id,site_id,tracking,counter,day,month,year) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`) if err != nil { // 处理错误 } defer stmt.Close() // 执行语句,按顺序传入你的10个参数值 _, err = stmt.Exec(idVal, advertiserNameVal, additionalVal, customerIdVal, siteIdVal, trackingVal, counterVal, dayVal, monthVal, yearVal) if err != nil { // 处理错误 } // 一切正常的话提交事务 err = txn.Commit() if err != nil { // 处理提交错误 }
另外给你个小简化技巧:如果这个插入操作只是单次执行,不需要重复复用预编译语句的话,可以直接用txn.Exec跳过Prepare步骤,代码会更简洁:
txn, err := db.Begin() if err != nil { // 处理错误 } defer txn.Rollback() _, err := txn.Exec(`INSERT INTO advertiser_per_day (id,advertiser_name,additional,customer_id,site_id,tracking,counter,day,month,year) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10)`, idVal, advertiserNameVal, additionalVal, customerIdVal, siteIdVal, trackingVal, counterVal, dayVal, monthVal, yearVal) if err != nil { // 处理错误 } err = txn.Commit() if err != nil { // 处理错误 }
最后提个小知识点:不同数据库的占位符规则不一样,比如MySQL用?,PostgreSQL用$N,SQLite两种都兼容,所以写跨数据库的Go代码时要特别注意这点哦。
内容的提问来源于stack exchange,提问作者Jurudocs
相关产品推荐
相关产品推荐

