プリペアドステートメントの使用
プリペアドステートメントを繰り返し使用するために定義できます。これにより、コードがデータベース操作を実行するたびにステートメントを再作成するオーバーヘッドを回避できるため、コードの実行速度が少し速くなります。
注意: プリペアドステートメントのパラメータープレースホルダーは、使用しているDBMSおよびドライバによって異なります。例えば、Postgres用のpqドライバは、?の代わりに$1のようなプレースホルダーを必要とします。
プリペアドステートメントとは?
プリペアドステートメントとは、DBMSによって解析され保存されたSQLであり、通常はプレースホルダーを含みますが、実際のパラメータ値は含まれません。その後、ステートメントは一連のパラメータ値とともに実行できます。
プリペアドステートメントの利用方法
同じSQLを繰り返し実行する予定がある場合は、sql.Stmtを使用してSQLステートメントを事前に準備し、必要に応じて実行できます。
以下の例では、データベースから特定のアルバムを選択するプリペアドステートメントを作成します。DB.Prepareは、指定されたSQLテキストのプリペアドステートメントを表すsql.Stmtを返します。SQLステートメントのパラメータをStmt.Exec、Stmt.QueryRow、またはStmt.Queryに渡してステートメントを実行できます。
// AlbumByID retrieves the specified album.
func AlbumByID(id int) (Album, error) {
// Define a prepared statement. You'd typically define the statement
// elsewhere and save it for use in functions such as this one.
stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
var album Album
// Execute the prepared statement, passing in an id value for the
// parameter whose placeholder is ?
err := stmt.QueryRow(id).Scan(&album.ID, &album.Title, &album.Artist, &album.Price, &album.Quantity)
if err != nil {
if err == sql.ErrNoRows {
// Handle the case of no rows returned.
}
return album, err
}
return album, nil
}
プリペアドステートメントの動作
プリペアドsql.Stmtは、ステートメントを呼び出すための通常のExec、QueryRow、およびQueryメソッドを提供します。これらのメソッドの使用方法の詳細については、データのクエリおよびデータを返さないSQLステートメントの実行を参照してください。
しかし、sql.StmtはすでにプリセットされたSQLステートメントを表しているため、そのExec、QueryRow、およびQueryメソッドは、SQLテキストを省略し、プレースホルダーに対応するSQLパラメータ値のみを受け取ります。
使用方法に応じて、新しいsql.Stmtをさまざまな方法で定義できます。
DB.PrepareおよびDB.PrepareContextは、DB.ExecおよびDB.Queryと同様に、トランザクションの外で単独で実行できるプリペアドステートメントを作成します。Tx.Prepare、Tx.PrepareContext、Tx.Stmt、およびTx.StmtContextは、特定のトランザクション内で使用するためのプリペアドステートメントを作成します。PrepareおよびPrepareContextはSQLテキストを使用してステートメントを定義します。StmtおよびStmtContextはDB.PrepareまたはDB.PrepareContextの結果を使用します。つまり、トランザクション用ではないsql.Stmtを、このトランザクション用のsql.Stmtに変換します。Conn.PrepareContextは、予約された接続を表すsql.Connからプリペアドステートメントを作成します。
コードがステートメントの処理を終えたら、必ずstmt.Closeを呼び出すようにしてください。これにより、ステートメントに関連付けられている可能性のあるデータベースリソース(基になる接続など)が解放されます。関数内のローカル変数にすぎないステートメントの場合は、defer stmt.Close()で十分です。
プリペアドステートメントを作成する関数
| 関数 | 説明 |
|---|---|
DB.PrepareDB.PrepareContext
|
単独で実行するため、またはTx.Stmtを使用してトランザクション内のプリペアドステートメントに変換されるステートメントを準備します。 |
Tx.PrepareTx.PrepareContextTx.StmtTx.StmtContext
|
特定のトランザクションで使用するためのステートメントを準備します。詳細については、トランザクションの実行を参照してください。 |
Conn.PrepareContext
|
予約済み接続での使用。詳細については、接続の管理を参照してください。 |