使用預處理語句
您可以定義一個預處理語句以供重複使用。這有助於您的程式碼執行得更快,避免了每次程式碼執行資料庫操作時重新建立語句的開銷。
注意:預處理語句中的引數佔位符因您使用的 DBMS 和驅動程式而異。例如,Postgres 的 pq 驅動程式 需要像 $1
這樣的佔位符,而不是 ?
。
什麼是預處理語句?
預處理語句是由 DBMS 解析和儲存的 SQL 語句,通常包含佔位符但沒有實際的引數值。稍後,可以使用一組引數值執行該語句。
如何使用預處理語句
當您期望重複執行相同的 SQL 時,可以使用 sql.Stmt
提前準備 SQL 語句,然後根據需要執行它。
以下示例建立了一個預處理語句,用於從資料庫中選擇特定的專輯。DB.Prepare
返回一個 sql.Stmt
,表示給定 SQL 文字的預處理語句。您可以將 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.Prepare DB.PrepareContext
|
準備一個獨立執行的語句,或將透過 Tx.Stmt 轉換為“事務內”預處理語句的語句。 |
Tx.Prepare Tx.PrepareContext Tx.Stmt Tx.StmtContext
|
準備一個用於特定事務的語句。有關更多資訊,請參閱執行事務。 |
Conn.PrepareContext
|
用於保留連線。有關更多資訊,請參閱管理連線。 |