行のクエリ
結果セットを読み取ります
「行のクエリ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
結果セットのクエリ
SELECTのように行を返す文にはQueryを使います。*sql.Rowsが返されるので、これを反復処理します。単一の値を取得する場合は、QueryRowのほうが簡単です。
db.Query
QueryはSQLを送信し、行とエラーを返します。行を使う前に、必ずエラーを確認してください。
rows, err := db.Query("SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
log.Fatal(err)
}必ずrows.Close()をdeferする
rowsは閉じられるまでデータベース接続を保持します。defer rows.Close()によって、接続がプールに返されます。これを忘れると、高負荷時に接続がリークします。
defer rows.Close()rows.Nextで反復する
rows.Next()は次の行へ進み、終端に達するとfalseを返します。ループ内ではScanを呼び出し、列の値を変数へコピーします。
for rows.Next() {
var id int
var name string
if err := rows.Scan(&id, &name); err != nil {
log.Fatal(err)
}
fmt.Println(id, name)
}Scanにはポインターを渡す
Scanは渡された変数に書き込むため、ポインター(&id、&name)を渡す必要があります。ポインターの数と順序は、選択した列と一致していなければなりません。
rows.Errを確認する
ループはデータをすべて読み終えたために終了する場合も、反復処理中にエラーが発生して終了する場合もあります。ループの後でrows.Err()を呼び出し、反復処理中のエラーを検出します。
if err := rows.Err(); err != nil {
log.Fatal(err)
}1行にはQueryRowを使う
1行だけ取得する想定なら、QueryRowとScanを組み合わせるほうが簡潔です。該当する行がない場合、Scanはsql.ErrNoRowsを返します。
var name string
err := db.QueryRow("SELECT name FROM users WHERE id = $1", 7).Scan(&name)
if err == sql.ErrNoRows {
fmt.Println("not found")
}実行可能なScanシミュレーション
実際のクエリにはデータベースが必要です。そのため、この実行可能な例では、インメモリのスライスに対してQuery、Next、Scanの流れを再現し、反復処理のパターンを示します。
package main
import "fmt"
type Row struct {
ID int
Name string
}
func main() {
rows := []Row{{1, "Ada"}, {2, "Lin"}, {3, "Guido"}}
for i := 0; i < len(rows); i++ {
var id int
var name string
id = rows[i].ID
name = rows[i].Name
fmt.Printf("id=%d name=%s\n", id, name)
}
fmt.Println("scanned", len(rows), "rows")
}NULLの処理
NULLの列は、通常のstringやintにはScanできません。sql.NullString、sql.NullInt64、またはポインター型を使い、NULLと空の値を区別できるようにします。
var email sql.NullString
rows.Scan(&email)
if email.Valid {
fmt.Println(email.String)
}構造体へのScan
標準ライブラリは、構造体全体ではなく個別の変数にScanします。&u.ID, &u.Nameを渡して、列を構造体のフィールドに対応付けます。sqlxのようなライブラリを使えば、この処理を自動化できます。
SELECT *を避ける
Scanの順序を安定させるため、列は明示的に列挙します。SELECT *に依存していると、スキーマ変更で列が追加されたとき、位置に依存するScanが気付かないまま壊れる可能性があります。
クイックチェック
クエリに関する知識を確認しましょう。
振り返り
行のクエリについて学びました。
- Queryは*sql.Rowsを返す。rows.Close()をdeferする
- rows.Nextでループし、Scanでポインターにコピーする
- ループ後にrows.Err()を確認する
- 1行の場合はQueryRowを使い、該当なしの場合はsql.ErrNoRowsになる
- NULLを許容する列にはNull型を使う
よくある質問
「行のクエリ」レッスンは無料ですか?
はい。「行のクエリ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「行のクエリ」で何を学びますか?
結果セットを読み取ります ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「行のクエリ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。