Go database/sql チュートリアル 09 - カラムが不明な場合

"Working with Unknown Columns" from database/sql tutorial

Go database/sqlチュートリアルのカラムが不明な場合の日本語意訳になります。


カラムが不明な場合

Scan() 関数へは正しい数の変数を正確に渡す必要があります。
クエリが何を返却するのか分からない場合はどうしたらいいでしょうか。

クエリで返却されるカラムの数が分からない場合、カラム名のリストを取得するために Columns() を使用できます。
このリストの長さからカラム数を確認し、正しい数の値のスライスを Scan() へ渡すことができます。
例えば、MySQLの派生版は SHOW PROCESSLIST コマンドで異なるカラムを返却するため、適切な処理をしないとエラーになってしまいます。

色々なやり方がありますが、以下は一例になります。

cols, err := rows.Columns()
if err != nil {
	// エラー処理
} else {
	dest := []interface{}{ // 正規のMySQLのカラム
		new(uint64), // id
		new(string), // host
		new(string), // user
		new(string), // db
		new(string), // command
		new(uint32), // time
		new(string), // state
		new(string), // info
	}
	if len(cols) == 11 {
		// Percona Serverの場合
	} else if len(cols) > 8 {
		// その他の派生版の場合
	}
	err = rows.Scan(dest...)
	// destの値の処理
}

カラムやその型が分からない場合は、 sql.RawBytes を使用する必要があります。

cols, err := rows.Columns() // errをチェックすることを忘れないでください
vals := make([]interface{}, len(cols))
for i, _ := range cols {
	vals[i] = new(sql.RawBytes)
}
for rows.Next() {
	err = rows.Scan(vals...)
	// valsの各要素がnilかどうかチェックし、
	// 型アサーションやreflectを用いて、カラムの値を型付の変数へ取得できます
}

前章: NULLの扱い方
次章: コネクションプール

 
comments powered by Disqus