Описание типа Stmt database/sql
Categories:
type Stmt
type Stmt struct {
// содержит отфильтрованные или неэкспортируемые поля
}
Stmt — это подготовленное выражение. Stmt безопасно для одновременного использования несколькими goroutines.
Если Stmt подготовлен на Tx или Conn, он будет навсегда привязан к одному базовому соединению. Если Tx или Conn закрывается, Stmt станет непригодным для использования, и все операции будут возвращать ошибку. Если Stmt подготовлен на DB, он будет оставаться пригодным для использования в течение всего срока жизни DB. Когда Stmt необходимо выполнить на новом базовом соединении, он автоматически подготовится на новом соединении.
Пример
package main
import (
"context"
"database/sql"
"log"
_ "github.com/go-sql-driver/mysql" // Добавляем импорт драйвера
)
func main() {
// Инициализируем контекст
ctx := context.Background()
// Инициализируем соединение с базой данных (в реальном коде)
db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Проверяем соединение
if err := db.PingContext(ctx); err != nil {
log.Fatal(err)
}
// Создаем подготовленное выражение
stmt, err := db.PrepareContext(ctx, "SELECT username FROM users WHERE id = ?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
// Выполняем запрос с параметром
id := 43
var username string
err = stmt.QueryRowContext(ctx, id).Scan(&username)
switch {
case err == sql.ErrNoRows:
log.Printf("no user with id %d", id) // Используем Printf вместо Fatalf чтобы не завершать программу
case err != nil:
log.Fatal(err)
default:
log.Printf("username is %s\n", username)
}
}
func (*Stmt) Close
func (s *Stmt) Close() error
Close закрывает оператор.
func (*Stmt) Exec
func (s *Stmt) Exec(args ...any) (Result, error)
Exec выполняет подготовленный оператор с заданными аргументами и возвращает Result, обобщающий результат оператора.
Exec использует context.Background внутренне; чтобы указать контекст, используйте Stmt.ExecContext.
func (*Stmt) ExecContext
func (s *Stmt) ExecContext(ctx context.Context, args ...any) (Result, error)
ExecContext выполняет подготовленное выражение с заданными аргументами и возвращает Result, обобщающий результат выражения.
func (*Stmt) Query
func (s *Stmt) Query(args ...any) (*Rows, error)
Query выполняет подготовленный запрос с заданными аргументами и возвращает результаты запроса в виде *Rows.
Query использует context.Background внутренне; для указания контекста используйте Stmt.QueryContext.
func (*Stmt) QueryContext ¶
func (s *Stmt) QueryContext(ctx context.Context, args ...any) (*Rows, error)
QueryContext выполняет подготовленное запросное выражение с заданными аргументами и возвращает результаты запроса в виде *Rows.
func (*Stmt) QueryRow
func (s *Stmt) QueryRow(args ...any) *Row
QueryRow выполняет подготовленный запрос с заданными аргументами. Если во время выполнения запроса происходит ошибка, она будет возвращена вызовом Scan на возвращенном *Row, который всегда не равен nil. Если запрос не выбирает никаких строк, *Row.Scan вернет ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.
Пример использования:
var name string
err := nameByUseridStmt.QueryRow(id).Scan(&name)
QueryRow использует context.Background внутренне; для указания контекста используйте Stmt.QueryRowContext.
func (*Stmt) QueryRowContext
func (s *Stmt) QueryRowContext(ctx context.Context, args ...any) *Row
QueryRowContext выполняет подготовленный запрос с заданными аргументами. Если во время выполнения запроса происходит ошибка, она будет возвращена вызовом Scan на возвращенном *Row, который всегда не равен nil. Если запрос не выбирает никаких строк, *Row.Scan вернет ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.
Пример
package main
import (
"context"
"database/sql"
"log"
_ "github.com/go-sql-driver/mysql" // Не забудьте импортировать драйвер
)
func main() {
// 1. Инициализация контекста
ctx := context.Background()
// 2. Инициализация подключения к БД (пример для MySQL)
db, err := sql.Open("mysql", "username:password@tcp(localhost:3306)/dbname")
if err != nil {
log.Fatal("Failed to connect to database:", err)
}
defer db.Close()
// 3. Проверка соединения
if err := db.PingContext(ctx); err != nil {
log.Fatal("Failed to ping database:", err)
}
// 4. Создание подготовленного выражения
stmt, err := db.PrepareContext(ctx, "SELECT username FROM users WHERE id = ?")
if err != nil {
log.Fatal("Failed to prepare statement:", err)
}
defer stmt.Close()
// 5. Выполнение запроса
id := 43
var username string
err = stmt.QueryRowContext(ctx, id).Scan(&username)
// 6. Обработка результатов
switch {
case err == sql.ErrNoRows:
log.Printf("User with id %d not found", id) // Не фатальная ошибка
case err != nil:
log.Fatal("Query failed:", err)
default:
log.Printf("Found user: %s (ID: %d)", username, id)
}
}