識別子(テーブル名や列名など)にプレースホルダーを使用することはできません。プレースホルダーは値用です。 。識別子はGoの変数名または関数名に似ていると考えることができるため、識別子にプレースホルダーを使用できることは、eval
を持つことに似ています。 さまざまなスクリプト言語のように。
これにより、fmt.Sprintf
を使用する必要がなくなります。 実行時まで識別子がわからない場合にSQLを構築するための同様の文字列操作:
col := "firstName"
sql := fmt.Sprintf("select %s from persons", col)
ただし、これによりSQLインジェクションと引用の問題が発生する可能性があるため、ある種のホワイトリストが必要になります。
quotedColumns := map[string]string{
"firstName": "`firstName`",
"lastName": "`lastName`",
...
}
quoted, ok := quotedColumns[columnName]
if !ok {
// Do something with the error here and run away...
}
sql := fmt.Sprintf("select %s from persons", quoted)
マップの値にMySQLバックティッククォートを含めたことに注意してください。識別子を引用/エスケープするための標準インターフェースには何もないので、自分で行う必要があります。すでにホワイトリストマップを手作業で作成している場合は、引用符を手作業で含めることもできます。それ以外の場合は、引用に関するMySQLのドキュメントを読み、いくつかの(うまくいけば)単純な文字列操作を実行することで、識別子の独自の引用関数を作成できます。