Sử dụng prepared statement
Bạn có thể định nghĩa một prepared statement để sử dụng lặp lại. Điều này giúp mã chạy nhanh hơn một chút bằng cách tránh chi phí tạo lại câu lệnh mỗi lần mã thực hiện thao tác cơ sở dữ liệu.
Lưu ý: Các placeholder tham số trong prepared statement thay đổi tùy theo
DBMS và driver bạn đang dùng. Ví dụ,
pq driver cho Postgres yêu cầu
placeholder dạng $1 thay vì ?.
Prepared statement là gì?
Prepared statement là SQL được phân tích cú pháp và lưu lại bởi DBMS, thường chứa các placeholder nhưng không có giá trị tham số thực tế. Sau đó, câu lệnh có thể được thực thi với một tập hợp các giá trị tham số.
Cách sử dụng prepared statement
Khi bạn muốn thực thi cùng một câu lệnh SQL nhiều lần, bạn có thể dùng
sql.Stmt để chuẩn bị câu lệnh SQL trước, sau đó thực thi nó khi cần.
Ví dụ dưới đây tạo một prepared statement chọn một album cụ thể từ cơ sở dữ
liệu. DB.Prepare trả về một
sql.Stmt đại diện cho prepared
statement cho một đoạn SQL nhất định. Bạn có thể truyền các tham số cho câu
lệnh SQL vào Stmt.Exec, Stmt.QueryRow hoặc Stmt.Query để chạy câu lệnh.
// 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
}
Hành vi của prepared statement
Một sql.Stmt đã được chuẩn bị cung
cấp các phương thức Exec, QueryRow và Query thông thường để gọi câu lệnh.
Để tìm hiểu thêm về cách sử dụng các phương thức này, xem
Truy vấn dữ liệu và
Thực thi các câu lệnh SQL không trả về dữ liệu.
Tuy nhiên, vì sql.Stmt đã đại diện cho một câu lệnh SQL cố định sẵn, các
phương thức Exec, QueryRow và Query của nó chỉ nhận các giá trị tham số
SQL tương ứng với placeholder, bỏ qua phần text SQL.
Bạn có thể định nghĩa sql.Stmt mới theo nhiều cách khác nhau, tùy thuộc vào
cách bạn sẽ sử dụng nó.
DB.PreparevàDB.PrepareContexttạo prepared statement có thể thực thi độc lập, bên ngoài transaction, giống nhưDB.ExecvàDB.Query.Tx.Prepare,Tx.PrepareContext,Tx.StmtvàTx.StmtContexttạo prepared statement để dùng trong một transaction cụ thể.PreparevàPrepareContextdùng text SQL để định nghĩa câu lệnh.StmtvàStmtContextdùng kết quả củaDB.PreparehoặcDB.PrepareContext, nghĩa là chúng chuyển đổi mộtsql.Stmtkhông dành cho transaction thànhsql.Stmtdành cho transaction này.Conn.PrepareContexttạo prepared statement từsql.Conn, đại diện cho một kết nối dành riêng.
Hãy đảm bảo stmt.Close được gọi khi mã của bạn dùng xong câu lệnh. Điều
này sẽ giải phóng mọi tài nguyên cơ sở dữ liệu (chẳng hạn các kết nối bên
dưới) có thể gắn với nó. Với các câu lệnh chỉ là biến cục bộ trong một hàm,
chỉ cần defer stmt.Close() là đủ.
Các hàm tạo prepared statement
| Hàm | Mô tả |
|---|---|
DB.PrepareDB.PrepareContext
|
Chuẩn bị câu lệnh để thực thi độc lập hoặc để chuyển đổi thành prepared statement trong transaction bằng Tx.Stmt. |
Tx.PrepareTx.PrepareContextTx.StmtTx.StmtContext
|
Chuẩn bị câu lệnh để dùng trong một transaction cụ thể. Để tìm hiểu thêm, xem Thực thi transaction. |
Conn.PrepareContext
|
Dùng với các kết nối dành riêng. Để tìm hiểu thêm, xem Quản lý kết nối. |