Описание типа Stmt database/sql

Stmt — это подготовленное выражение. Stmt безопасно для одновременного использования несколькими goroutines.

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)
	}
}