準備されたステートメントの使用
繰り返し使用するために準備されたステートメントを定義できます。 これにより、コードがデータベース操作を実行するたびにステートメントを再作成するオーバーヘッドを回避することで、コードの実行速度を少し向上させることができます。
注: 準備されたステートメントのパラメータプレースホルダーは、使用している 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)
}
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.Prepare DB.PrepareContext
|
単独で実行するか、Tx.Stmt を使用してトランザクション内の準備済みステートメントに変換されるステートメントを準備します。 |
Tx.Prepare Tx.PrepareContext Tx.Stmt Tx.StmtContext
|
特定のトランザクションで使用するステートメントを準備します。 詳細については、トランザクションの実行 を参照してください。 |
Conn.PrepareContext
|
予約された接続で使用します。 詳細については、接続の管理 を参照してください。 |