0Pricing
Go Academy · レッスン

行のクエリ

結果セットを読み取ります

「行のクエリ」は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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 接続の開始
  2. 行のクエリ
  3. プリペアドステートメント
  4. トランザクション
← Go Academyに戻る