🤷‍♂️

Docker上のGoでMySQLを使うときに、躓いた(Error 1064)

2022/06/25に公開

Docker上のGoでMySQLを使うときに、Insert文を実行すると

panic: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'generated(owner, repository) VALUES( ?, ? )' at line 1

というエラーが出てきました。パッケージのGitHub[1]を参考に書いたのですが、どうも、書き方がまずかったようです。

解決策を備忘録として、共有したいと思います。
なぜ、最初に書いたコードでうまくいかなかったのかは、ちょっと分からないので、詳しい方、ご教授いただけると幸いです…

最初に書いたコード

今回使っているパッケージはgithub.com/go-sql-driver/mysql[2]です。
そして、今回、コードを書くにあたってパッケージ公式のREADME[2:1]、Example[1:1]とMasaoさんの記事[3]、そして前にMariaDBを使っていた名残でMariaDBのドキュメント[4]も参考にしました。

mDB.go
package mDB

import (
	"database/sql"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

type MDB struct {
	Host     string
	User     string
	Password string
	Database string
}

func (m MDB) Test() {
	db, er := sql.Open("mysql", m.User+":"+m.Password+"@"+"tcp("+m.Host+":3306)"+"/"+m.Database)
	if er != nil {
		log.Fatal(er)
	}
	defer db.Close()

	er = db.Ping()
	if er != nil {
		panic(er.Error())
	}

	stmtIns, err := db.Prepare("insert into generated(owner, repository) values( ?, ? )")
	if err != nil {
		panic(err.Error()) // proper error handling instead of panic in your app
	}
	defer stmtIns.Close() // Close the statement when we leave main() / the program terminates

	stmtIns.Exec("Hacknock", "testdayo")
}

このmDB.Test()を実行すると

panic: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'generated(owner, repository) values( ?, ? )' at line 1 [recovered]
panic: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'generated(owner, repository) values( ?, ? )' at line 1

と出てきます。
ほとんど、サンプルコード通りなのに…

うまくいったコード

いろいろ試した結果、SQL文のinsert文を

insert into [データベース名].generated(owner, repository) values( ?, ? )

とすればいいことがわかりました。
sql.Openでデータベース名指定しているのに…なぜ…?
結果、以下のコードでうまく動きます。

mDB.go
package mDB

import (
	"database/sql"
	"log"

	_ "github.com/go-sql-driver/mysql"
)

type MDB struct {
	Host     string
	User     string
	Password string
	Database string
}

func (m MDB) Test() {
	db, er := sql.Open("mysql", m.User+":"+m.Password+"@"+"tcp("+m.Host+":3306)"+"/"+m.Database)
	if er != nil {
		log.Fatal(er)
	}
	defer db.Close()

	er = db.Ping()
	if er != nil {
		panic(er.Error())
	}

	stmtIns, err := db.Prepare("insert into " + m.Database + ".generated(owner, repository) values( ?, ? )")
	if err != nil {
		panic(err.Error()) // proper error handling instead of panic in your app
	}
	defer stmtIns.Close() // Close the statement when we leave main() / the program terminates

	stmtIns.Exec("Hacknock", "testdayo")
}
脚注
  1. Examples / (go-sql-driver / mysql) https://github.com/go-sql-driver/mysql/wiki/Examples#a-word-on-sqlopen (2022-06-25閲覧) ↩︎ ↩︎

  2. go-sql-driver / mysql https://github.com/go-sql-driver/mysql (2022-06-25閲覧) ↩︎ ↩︎

  3. go言語 mysqlに接続してinsertを実行する / Masao https://mebee.info/2022/06/23/post-53678/ (2022-06-25閲覧) ↩︎

  4. Go 言語から MariaDB Server を使ってみる / MariaDB https://mariadb.com/ja/resources/blog/golang-with-mariadb/ (2022-06-25閲覧) ↩︎

Discussion