Go SQL Interface (Japanese)

"SQL Interface" from golang wiki

Go公式WikiのSQL Interfaceの日本語意訳になります。
(元記事の最終更新日: 2017/06/06 rev.4)

SQLインターフェースの簡単な説明になります。


SQLインターフェース

はじめに

database/sqlパッケージはSQL(またはSQL風の)データベースに関して一般的なインターフェースを提供しています。詳細については公式ドキュメントを参照してください。

このページでは使用パターンの例を掲載しています。

データベース・ドライバ

database/sqlパッケージは必ずデータベースドライバと一緒に組み合わせて使います。
ドライバのリストを http://golang.org/s/sqldrivers で確認してください。

以下のドキュメントではドライバが既にインポートされている事を想定しています。

データベースへの接続

Openはデータベースハンドラの作成のために使われます。

db, err := sql.Open(driver, dataSourceName)

driverはデータベースドライバを指定し、dataSourceNameはDB名や認証情報といったデータベース固有の接続情報を指定します。

Openがデータベース接続を直接開かないことに注意してください。
クエリが作られるまでは接続は延期されます。クエリ作成の前に接続を確かめたい場合は、Ping関数を使います。

if err := db.Ping(); err != nil {
  log.Fatal(err)
}

データベースの使用後には、Closeによってクローズされます。

クエリの実行

Execは行を一切返却しないクエリの実行に使われます。

result, err := db.Exec(
	"INSERT INTO users (name, age) VALUES ($1, $2)",
	"gopher",
	27,
)

resultには最終挿入行のIDや変更行数が入ります。これらの値の利用可否はデータベースドライバによって異なります。

Queryは取得のために使います。

rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
if err != nil {
	log.Fatal(err)
}
for rows.Next() {
	var name string
	if err := rows.Scan(&name); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s は %d\n", name, age)
}
if err := rows.Err(); err != nil {
	log.Fatal(err)
}

QueryRow は単一の行のみが想定される場合に使います。

var age int64
row := db.QueryRow("SELECT age FROM users WHERE name = $1", name)
err := row.Scan(&age)

プリペアドステートメントはPrepareによって作成可能です。

age := 27
stmt, err := db.Prepare("SELECT name FROM users WHERE age = $1")
if err != nil {
	log.Fatal(err)
}
rows, err := stmt.Query(age)
// 以下 行の処理...

ExecQuery、そしてQueryRowはステートメント(Prepareによって作られるdb.Stmt)から呼び出すことができます。
ステートメントの使用後には、Closeで閉じましょう。

トランザクション

トランザクションはBeginによって開始されます。

tx, err := db.Begin()
if err != nil {
	log.Fatal(err)
}

ExecQueryQueryRow、そしてPrepare関数はトランザクション内で使うことができます。

トランザクションの最後にはCommitRollbackを呼び出します。

NULLへの対処

もしデータベースのカラムがNULL許可の場合、NULL値を許可する型の一つをScan
に渡してください。

たとえば、namesテーブルのnameカラムがNULL許可の場合は以下のようにします。

var name NullString
err := db.QueryRow("SELECT name FROM names WHERE id = $1", id).Scan(&name)
...
if name.Valid {
	// name.Stringを使う
} else {
	// 値はNULL
}

database/sqlでは、NullBoolNullFloat64NullInt64NullStringのみが実装されています。
データベース固有のNULL型の実装はデータベースドライバに委ねられています。

 
comments powered by Disqus