初めに
Go言語においてSQLのqueryに(可変長な)複数のパラメータの渡したかったのですが、いい記事が見つからなかったのでまとめてみました!同じことで困っている人の一助になれれば幸いです!!
環境
Hard: Inter Mac
OS: Monterey 12.0.1
Golang: go version go1.20.5 darwin/amd64
事前に知っていたこと
Go言語ではsymbol(手元の環境では '?' )を SQL query に指定することで変数を受け取り可能です。
一つの例を示します。
rows, _ := db.Query("SELECT * FROM テーブル名 WHERE address LIKE '%?'",変数)
(参考資料より引用)
やりたいこと
上記の query で指定している変数が状況に応じて要素数が変化するような配列データだった場合に、Go言語ではどのように記述することができるのでしょうか?
事前情報をもとにできたこと
複数の値を指定したい場合は、配列データの要素数分symbolを追加してやれば良いので下記のように書くことが可能です。(カンマ区切りで複数指定可能)
// arr は可変長の配列
strings.Repeat(",<環境に合ったsymbol>", len(arr)-1)
rep_str := strings.Repeat は第一引数の文字列を第二引数回繰り返し結合した文字列を出力する関数です。 query にこの rep_str を fmt.Sprintf などで結合させれば、引数を arr の要素個受け付ける query の土台の完成です。
困ったこと
query の宣言ができた一方で、値はどのように受け渡すことができるのでしょうか...? 直接指定? for文で複数回指定? (Pythonなら *<配列> とすることで各要素取り出せた気がするのでGoにもそれ相当のものがある?)
解決方法
Go言語では関数宣言時に引数として "..." という宣言がなされている場合は 引数を渡す際に " ..." のようにすることで可変長引数を渡すことが可能らしいのです。(参考資料)
Go言語の公式ドキュメントでQuery実行関連の関数(DB.Query, DB.QueryRow etc...)を確認すると、下記のように定義されていることが確認できる。
func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
"srgs ...any" と宣言されていることから any型の配列orスライスならそのまま引数に渡せることがわかります!
any型の代表的なものとしてinterface型というものがあり、事前情報をもとにできたことで受け取る可変長引数データのarrをinterface型に変換する(interfaceへの変換についてはこちらに情報あり)ことで引数に渡すことが可能になりました!!
終わりに
今回はGo言語におけるSQL querへの可変長な複数パラメータの渡し方について確認しました。
Goを勉強し始めてまだ1ヶ月くらいなので間違いもたくさんあると思います。もし間違いを発見されましたらコメント等でお教えいただけると幸いです!