1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Go SQL チートシート

Posted at

Go SQL チートシート

Goの標準ライブラリ「database/sql」を使ったSQLの基本操作をまとめたチートシートです。簡単な説明とともにコードサンプルを紹介します。

1. インポート & ドライバ設定

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"  // 使用するデータベースドライバ(MySQLの場合)をインポート
    // _ "github.com/lib/pq"  // PostgreSQLの場合はこのように別のドライバをインポート
)
  • database/sql: Go標準のSQLデータベースインターフェース。
  • _ は、ドライバパッケージを明示的に使用しないが、初期化は行う必要があるために使う。

2. データベースに接続

db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/dbname")
if err != nil {
    log.Fatal(err)  // エラー発生時にプログラムを終了させる
}
defer db.Close()    // 関数終了時に接続を閉じる
  • sql.Open: データベースへの接続を開始。接続自体はまだ確立されていない。
  • defer db.Close(): 関数が終了する際にデータベース接続を閉じるための予約。

3. データベースにPingを送る

err = db.Ping()
if err != nil {
    log.Fatal(err)  // 接続が確立されていない場合、エラーメッセージを表示して終了
}
  • Ping(): 実際にデータベースに接続して通信ができるか確認する。

4. クエリ実行(SELECT)

4.1 単一行を取得 (QueryRow)

var name string
err := db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)
if err != nil {
    log.Fatal(err)  // エラー発生時にエラーメッセージを表示
}
fmt.Println(name)  // 取得した名前を表示
  • QueryRow: 結果が1行のクエリを実行する際に使用。
  • Scan: データベースから取得した値をGoの変数にマッピング。

4.2 複数行を取得 (Query)

rows, err := db.Query("SELECT id, name FROM users")
if err != nil {
    log.Fatal(err)  // クエリ実行時にエラーがあれば終了
}
defer rows.Close()  // `rows`は使用後に必ず閉じる

for rows.Next() {  // 次の行が存在する限りループを実行
    var id int
    var name string
    err := rows.Scan(&id, &name)  // カラムの値を変数に格納
    if err != nil {
        log.Fatal(err)  // エラーが発生した場合終了
    }
    fmt.Printf("ID: %d, Name: %s\n", id, name)  // 取得したデータを表示
}

if err := rows.Err(); err != nil {  // クエリ中のエラーチェック
    log.Fatal(err)
}
  • Query: 複数行を取得する際に使用。
  • rows.Next(): 次の行が存在するか確認してループを継続。
  • Scan: 各行のカラムを変数にマッピング。

5. データ挿入 (INSERT)

result, err := db.Exec("INSERT INTO users (name, age) VALUES (?, ?)", "Alice", 30)
if err != nil {
    log.Fatal(err)  // 挿入時にエラーがあれば終了
}

lastInsertID, err := result.LastInsertId()  // 最後に挿入された行のIDを取得
if err != nil {
    log.Fatal(err)  // エラーがあれば終了
}
fmt.Println("Last Insert ID:", lastInsertID)  // 挿入したレコードのIDを表示
  • Exec: データベースの変更系操作(INSERT, UPDATE, DELETE)に使用。
  • LastInsertId: 挿入した行のIDを取得する。

6. データ更新 (UPDATE)

result, err := db.Exec("UPDATE users SET age = ? WHERE id = ?", 31, 1)
if err != nil {
    log.Fatal(err)  // 更新時にエラーがあれば終了
}

rowsAffected, err := result.RowsAffected()  // 更新された行数を取得
if err != nil {
    log.Fatal(err)  // エラーがあれば終了
}
fmt.Println("Rows Affected:", rowsAffected)  // 更新された行数を表示
  • RowsAffected: 更新された行数を取得できる。

7. データ削除 (DELETE)

result, err := db.Exec("DELETE FROM users WHERE id = ?", 1)
if err != nil {
    log.Fatal(err)  // 削除時にエラーがあれば終了
}

rowsAffected, err := result.RowsAffected()  // 削除された行数を取得
if err != nil {
    log.Fatal(err)  // エラーがあれば終了
}
fmt.Println("Rows Affected:", rowsAffected)  // 削除された行数を表示
  • DELETEクエリもExecで実行し、影響を受けた行数を確認。

8. トランザクション処理

tx, err := db.Begin()  // トランザクションの開始
if err != nil {
    log.Fatal(err)  // エラーがあれば終了
}

_, err = tx.Exec("UPDATE accounts SET balance = balance - 100 WHERE id = ?", 1)  // 口座1から100を減額
if err != nil {
    tx.Rollback()  // エラー発生時はトランザクションをロールバック
    log.Fatal(err)
}

_, err = tx.Exec("UPDATE accounts SET balance = balance + 100 WHERE id = ?", 2)  // 口座2に100を加算
if err != nil {
    tx.Rollback()  // エラー発生時はトランザクションをロールバック
    log.Fatal(err)
}

err = tx.Commit()  // 成功したらトランザクションを確定
if err != nil {
    log.Fatal(err)  // コミット時にエラーがあれば終了
}
  • Begin: トランザクションを開始。
  • Rollback: エラー時にロールバック。
  • Commit: トランザクションが正常に完了したらコミットして確定。

9. プリペアドステートメント (Prepared Statements)

stmt, err := db.Prepare("INSERT INTO users (name, age) VALUES (?, ?)")
if err != nil {
    log.Fatal(err)  // 準備時にエラーがあれば終了
}
defer stmt.Close()  // 使用後は必ずクローズ

_, err = stmt.Exec("Bob", 25)  // 準備したステートメントでクエリを実行
if err != nil {
    log.Fatal(err)  // 実行時にエラーがあれば終了
}

_, err = stmt.Exec("Charlie", 29)  // 別のデータを実行
if err != nil {
    log.Fatal(err)  // 実行時にエラーがあれば終了
}
  • Prepare: 複数回同じクエリを実行する場合に有効。パフォーマンスが向上。
  • Exec: 準備されたステートメントを実行。

10. Null値の処理

var age sql.NullInt64
err := db.QueryRow("SELECT age FROM users WHERE id = ?", 1).Scan(&age)
if err != nil {
    log.Fatal(err)  // クエリ実行時にエラーがあれば終了
}

if age.Valid {
    fmt.Println("Age:", age.Int64)  // NULLでない場合、値を表示
} else {
    fmt.Println("Age is NULL")  // NULLの場合は「NULL」と表示
}
  • sql.NullInt64sql.NullStringなどを使って、データベースのNULL値を扱うことができる。
  • Validフィールドで、値がNULLかどうかを確認する。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?