Spec-Zone.ru › Go

Пакет sql

  • import "database/sql"
  • Обзор
  • Указатель
  • Примеры
  • Подкаталоги

Обзор

Пакет sql предоставляет универсальный интерфейс для работы с базами данных SQL (или подобными SQL).

Пакет sql необходимо использовать совместно с драйвером базы данных. Список драйверов см. на странице https://golang.org/s/sqldrivers.

Драйверы, не поддерживающие отмену контекста, не вернут управление до завершения запроса.

Примеры использования см. на странице вики https://golang.org/s/sqlwiki.

Пример (OpenDBCLI)

Код:

package sql_test

import (
    "context"
    "database/sql"
    "flag"
    "log"
    "os"
    "os/signal"
    "time"
)

var pool *sql.DB // Database connection pool.

func Example_openDBCLI() {
    id := flag.Int64("id", 0, "person ID to find")
    dsn := flag.String("dsn", os.Getenv("DSN"), "connection data source name")
    flag.Parse()

    if len(*dsn) == 0 {
        log.Fatal("missing dsn flag")
    }
    if *id == 0 {
        log.Fatal("missing person ID")
    }
    var err error

    // Opening a driver typically will not attempt to connect to the database.
    pool, err = sql.Open("driver-name", *dsn)
    if err != nil {
        // This will not be a connection error, but a DSN parse error or
        // another initialization error.
        log.Fatal("unable to use data source name", err)
    }
    defer pool.Close()

    pool.SetConnMaxLifetime(0)
    pool.SetMaxIdleConns(3)
    pool.SetMaxOpenConns(3)

    ctx, stop := context.WithCancel(context.Background())
    defer stop()

    appSignal := make(chan os.Signal, 3)
    signal.Notify(appSignal, os.Interrupt)

    go func() {
        <-appSignal
        stop()
    }()

    Ping(ctx)

    Query(ctx, *id)
}

// Ping the database to verify DSN provided by the user is valid and the
// server accessible. If the ping fails exit the program with an error.
func Ping(ctx context.Context) {
    ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
    defer cancel()

    if err := pool.PingContext(ctx); err != nil {
        log.Fatalf("unable to connect to database: %v", err)
    }
}

// Query the database for the information requested and prints the results.
// If the query fails exit the program with an error.
func Query(ctx context.Context, id int64) {
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()

    var name string
    err := pool.QueryRowContext(ctx, "select p.name from people as p where p.id = :id;", sql.Named("id", id)).Scan(&name)
    if err != nil {
        log.Fatal("unable to execute search query", err)
    }
    log.Println("name=", name)
}

Пример (OpenDBService)

Код:

package sql_test

import (
    "context"
    "database/sql"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "net/http"
    "time"
)

func Example_openDBService() {
    // Opening a driver typically will not attempt to connect to the database.
    db, err := sql.Open("driver-name", "database=test1")
    if err != nil {
        // This will not be a connection error, but a DSN parse error or
        // another initialization error.
        log.Fatal(err)
    }
    db.SetConnMaxLifetime(0)
    db.SetMaxIdleConns(50)
    db.SetMaxOpenConns(50)

    s := &Service{db: db}

    http.ListenAndServe(":8080", s)
}

type Service struct {
    db *sql.DB
}

func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    db := s.db
    switch r.URL.Path {
    default:
        http.Error(w, "not found", http.StatusNotFound)
        return
    case "/healthz":
        ctx, cancel := context.WithTimeout(r.Context(), 1*time.Second)
        defer cancel()

        err := s.db.PingContext(ctx)
        if err != nil {
            http.Error(w, fmt.Sprintf("db down: %v", err), http.StatusFailedDependency)
            return
        }
        w.WriteHeader(http.StatusOK)
        return
    case "/quick-action":
        // This is a short SELECT. Use the request context as the base of
        // the context timeout.
        ctx, cancel := context.WithTimeout(r.Context(), 3*time.Second)
        defer cancel()

        id := 5
        org := 10
        var name string
        err := db.QueryRowContext(ctx, `
select
    p.name
from
    people as p
    join organization as o on p.organization = o.id
where
    p.id = :id
    and o.id = :org
;`,
            sql.Named("id", id),
            sql.Named("org", org),
        ).Scan(&name)
        if err != nil {
            if err == sql.ErrNoRows {
                http.Error(w, "not found", http.StatusNotFound)
                return
            }
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        io.WriteString(w, name)
        return
    case "/long-action":
        // This is a long SELECT. Use the request context as the base of
        // the context timeout, but give it some time to finish. If
        // the client cancels before the query is done the query will also
        // be canceled.
        ctx, cancel := context.WithTimeout(r.Context(), 60*time.Second)
        defer cancel()

        var names []string
        rows, err := db.QueryContext(ctx, "select p.name from people as p where p.active = true;")
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        for rows.Next() {
            var name string
            err = rows.Scan(&name)
            if err != nil {
                break
            }
            names = append(names, name)
        }
        // Check for errors during rows "Close".
        // This may be more important if multiple statements are executed
        // in a single batch and rows were written as well as read.
        if closeErr := rows.Close(); closeErr != nil {
            http.Error(w, closeErr.Error(), http.StatusInternalServerError)
            return
        }

        // Check for row scan error.
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        // Check for errors during row iteration.
        if err = rows.Err(); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }

        json.NewEncoder(w).Encode(names)
        return
    case "/async-action":
        // This action has side effects that we want to preserve
        // even if the client cancels the HTTP request part way through.
        // For this we do not use the http request context as a base for
        // the timeout.
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        var orderRef = "ABC123"
        tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        _, err = tx.ExecContext(ctx, "stored_proc_name", orderRef)

        if err != nil {
            tx.Rollback()
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        err = tx.Commit()
        if err != nil {
            http.Error(w, "action in unknown state, check state before attempting again", http.StatusInternalServerError)
            return
        }
        w.WriteHeader(http.StatusOK)
        return
    }
}

Указатель

  • Переменные
  • func ConvertAssign(scanCtx driver.ScanContext, dest any, src driver.Value) error
  • func Drivers() []string
  • func Register(name string, driver driver.Driver)
  • type ColumnType
  • func (ci *ColumnType) DatabaseTypeName() string
  • func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool)
  • func (ci *ColumnType) Length() (length int64, ok bool)
  • func (ci *ColumnType) Name() string
  • func (ci *ColumnType) Nullable() (nullable, ok bool)
  • func (ci *ColumnType) ScanType() reflect.Type
  • type Conn
  • func (c *Conn) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)
  • func (c *Conn) Close() error
  • func (c *Conn) ExecContext(ctx context.Context, query string, args ...any) (Result, error)
  • func (c *Conn) PingContext(ctx context.Context) error
  • func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error)
  • func (c *Conn) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
  • func (c *Conn) QueryRowContext(ctx context.Context, query string, args ...any) *Row
  • func (c *Conn) Raw(f func(driverConn any) error) (err error)
  • type DB
  • func Open(driverName, dataSourceName string) (*DB, error)
  • func OpenDB(c driver.Connector) *DB
  • func (db *DB) Begin() (*Tx, error)
  • func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)
  • func (db *DB) Close() error
  • func (db *DB) Conn(ctx context.Context) (*Conn, error)
  • func (db *DB) Driver() driver.Driver
  • func (db *DB) Exec(query string, args ...any) (Result, error)
  • func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error)
  • func (db *DB) Ping() error
  • func (db *DB) PingContext(ctx context.Context) error
  • func (db *DB) Prepare(query string) (*Stmt, error)
  • func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error)
  • func (db *DB) Query(query string, args ...any) (*Rows, error)
  • func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
  • func (db *DB) QueryRow(query string, args ...any) *Row
  • func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row
  • func (db *DB) SetConnMaxIdleTime(d time.Duration)
  • func (db *DB) SetConnMaxLifetime(d time.Duration)
  • func (db *DB) SetMaxIdleConns(n int)
  • func (db *DB) SetMaxOpenConns(n int)
  • func (db *DB) Stats() DBStats
  • type DBStats
  • type IsolationLevel
  • func (i IsolationLevel) String() string
  • type NamedArg
  • func Named(name string, value any) NamedArg
  • type Null
  • func (n *Null[T]) Scan(value any) error
  • func (n Null[T]) Value() (driver.Value, error)
  • type NullBool
  • func (n *NullBool) Scan(value any) error
  • func (n NullBool) Value() (driver.Value, error)
  • type NullByte
  • func (n *NullByte) Scan(value any) error
  • func (n NullByte) Value() (driver.Value, error)
  • type NullFloat64
  • func (n *NullFloat64) Scan(value any) error
  • func (n NullFloat64) Value() (driver.Value, error)
  • type NullInt16
  • func (n *NullInt16) Scan(value any) error
  • func (n NullInt16) Value() (driver.Value, error)
  • type NullInt32
  • func (n *NullInt32) Scan(value any) error
  • func (n NullInt32) Value() (driver.Value, error)
  • type NullInt64
  • func (n *NullInt64) Scan(value any) error
  • func (n NullInt64) Value() (driver.Value, error)
  • type NullString
  • func (ns *NullString) Scan(value any) error
  • func (ns NullString) Value() (driver.Value, error)
  • type NullTime
  • func (n *NullTime) Scan(value any) error
  • func (n NullTime) Value() (driver.Value, error)
  • type Out
  • type RawBytes
  • type Result
  • type Row
  • func (r *Row) Err() error
  • func (r *Row) Scan(dest ...any) error
  • type Rows
  • func (rs *Rows) Close() error
  • func (rs *Rows) ColumnTypes() ([]*ColumnType, error)
  • func (rs *Rows) Columns() ([]string, error)
  • func (rs *Rows) Err() error
  • func (rs *Rows) Next() bool
  • func (rs *Rows) NextResultSet() bool
  • func (rs *Rows) Scan(dest ...any) error
  • type Scanner
  • type Stmt
  • func (s *Stmt) Close() error
  • func (s *Stmt) Exec(args ...any) (Result, error)
  • func (s *Stmt) ExecContext(ctx context.Context, args ...any) (Result, error)
  • func (s *Stmt) Query(args ...any) (*Rows, error)
  • func (s *Stmt) QueryContext(ctx context.Context, args ...any) (*Rows, error)
  • func (s *Stmt) QueryRow(args ...any) *Row
  • func (s *Stmt) QueryRowContext(ctx context.Context, args ...any) *Row
  • type Tx
  • func (tx *Tx) Commit() error
  • func (tx *Tx) Exec(query string, args ...any) (Result, error)
  • func (tx *Tx) ExecContext(ctx context.Context, query string, args ...any) (Result, error)
  • func (tx *Tx) Prepare(query string) (*Stmt, error)
  • func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error)
  • func (tx *Tx) Query(query string, args ...any) (*Rows, error)
  • func (tx *Tx) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)
  • func (tx *Tx) QueryRow(query string, args ...any) *Row
  • func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...any) *Row
  • func (tx *Tx) Rollback() error
  • func (tx *Tx) Stmt(stmt *Stmt) *Stmt
  • func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt
  • type TxOptions

Примеры

Conn.ExecContext
DB.BeginTx
DB.ExecContext
DB.PingContext
DB.Prepare
DB.QueryContext
DB.QueryRowContext
DB.Query (MultipleResultSets)
Rows
Stmt
Stmt.QueryRowContext
Tx.ExecContext
Tx.Prepare
Tx.Rollback
Package (OpenDBCLI)
Package (OpenDBService)

Файлы пакета

closemu.go convert.go ctxutil.go sql.go

Переменные

ErrConnDone возвращается при выполнении любой операции с подключением, которое уже было возвращено в пул подключений.

var ErrConnDone = errors.New("sql: connection is already closed")

ErrNoRows возвращается методом Row.Scan, если DB.QueryRow не возвращает строку. В этом случае QueryRow возвращает значение-заполнитель *Row, которое откладывает возникновение этой ошибки до вызова Scan.

var ErrNoRows = errors.New("sql: no rows in result set")

ErrTxDone возвращается при выполнении любой операции с транзакцией, которая уже была зафиксирована или отменена.

var ErrTxDone = errors.New("sql: transaction has already been committed or rolled back")

func ConvertAssign 1.27

func ConvertAssign(scanCtx driver.ScanContext, dest any, src driver.Value) error

ConvertAssign копирует значение src в значение, на которое указывает dest. Подробные сведения о преобразованиях см. в документации к Rows.Scan. dest должен быть указателем или реализовывать интерфейс Scanner.

Реализации driver.RowsColumnScanner должны передавать параметр driver.ScanContext. В остальных случаях передавайте в качестве контекста driver.ScanContext{}.

ConvertAssign предназначена для использования реализациями драйверов. Большинству пользователей не нужно вызывать её напрямую.

func Drivers 1.4

func Drivers() []string

Drivers возвращает отсортированный список имён зарегистрированных драйверов.

func Register

func Register(name string, driver driver.Driver)

Register делает драйвер базы данных доступным под указанным именем. Если Register вызывается дважды с одним и тем же именем или если driver равен nil, функция вызывает панику.

type ColumnType 1.8

ColumnType содержит имя и тип столбца.

type ColumnType struct {
    // contains filtered or unexported fields
}

func (*ColumnType) DatabaseTypeName 1.8

func (ci *ColumnType) DatabaseTypeName() string

DatabaseTypeName возвращает системное имя типа столбца в базе данных. Если возвращена пустая строка, имя типа драйвера не поддерживается. Список типов данных драйвера см. в его документации. Спецификаторы ColumnType.Length не включаются. К распространённым именам типов относятся "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", "INT" и "BIGINT".

func (*ColumnType) DecimalSize 1.8

func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool)

DecimalSize возвращает масштаб и точность десятичного типа. Если это неприменимо или не поддерживается, ok равно false.

func (*ColumnType) Length 1.8

func (ci *ColumnType) Length() (length int64, ok bool)

Length возвращает длину типа столбца для типов переменной длины, таких как текстовые и двоичные поля. Если длина типа не ограничена, значение будет равно math.MaxInt64 (при этом ограничения базы данных по-прежнему применяются). Если тип столбца не имеет переменной длины, например int, или драйвер не поддерживает это свойство, ok равно false.

func (*ColumnType) Name 1.8

func (ci *ColumnType) Name() string

Name возвращает имя или псевдоним столбца.

func (*ColumnType) Nullable 1.8

func (ci *ColumnType) Nullable() (nullable, ok bool)

Nullable сообщает, может ли столбец содержать значение null. Если драйвер не поддерживает это свойство, ok будет равно false.

func (*ColumnType) ScanType 1.8

func (ci *ColumnType) ScanType() reflect.Type

ScanType возвращает тип Go, подходящий для сканирования с помощью Rows.Scan. Если драйвер не поддерживает это свойство, ScanType вернёт тип пустого интерфейса.

type Conn 1.9

Conn представляет одно подключение к базе данных, а не пул подключений. Предпочтительно выполнять запросы через DB, если нет особой необходимости постоянно использовать одно подключение к базе данных.

Для возврата подключения в пул базы данных необходимо вызвать Conn.Close. Это можно сделать одновременно с выполняющимся запросом.

После вызова Conn.Close все операции с подключением завершаются ошибкой ErrConnDone.

type Conn struct {
    // contains filtered or unexported fields
}

func (*Conn) BeginTx 1.9

func (c *Conn) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)

BeginTx начинает транзакцию.

Указанный контекст используется до фиксации или отката транзакции. Если контекст отменён, пакет sql выполнит откат транзакции. Tx.Commit вернёт ошибку, если контекст, переданный в BeginTx, был отменён.

Указанный TxOptions является необязательным и может быть nil, если следует использовать значения по умолчанию. Если используется уровень изоляции, отличный от стандартного, который драйвер не поддерживает, будет возвращена ошибка.

func (*Conn) Close 1.9

func (c *Conn) Close() error

Close возвращает соединение в пул соединений. Все операции после вызова Close завершатся с ошибкой ErrConnDone. Close можно безопасно вызывать параллельно с другими операциями; вызов будет заблокирован до завершения всех остальных операций. Может быть полезно сначала отменить используемый контекст, а затем сразу вызвать close.

func (*Conn) ExecContext 1.9

func (c *Conn) ExecContext(ctx context.Context, query string, args ...any) (Result, error)

ExecContext выполняет запрос, не возвращая строк. Аргументы используются для параметров-заполнителей в запросе.

Пример

Код:

// A *DB is a pool of connections. Call Conn to reserve a connection for
// exclusive use.
conn, err := db.Conn(ctx)
if err != nil {
    log.Fatal(err)
}
defer conn.Close() // Return the connection to the pool.
id := 41
result, err := conn.ExecContext(ctx, `UPDATE balances SET balance = balance + 10 WHERE user_id = ?;`, id)
if err != nil {
    log.Fatal(err)
}
rows, err := result.RowsAffected()
if err != nil {
    log.Fatal(err)
}
if rows != 1 {
    log.Fatalf("expected single row affected, got %d rows affected", rows)
}

func (*Conn) PingContext 1.9

func (c *Conn) PingContext(ctx context.Context) error

PingContext проверяет, что соединение с базой данных всё ещё активно.

func (*Conn) PrepareContext 1.9

func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error)

PrepareContext создаёт подготовленный оператор для последующих запросов или выполнений. Из возвращённого оператора можно параллельно выполнять несколько запросов или команд. Когда оператор больше не нужен, вызывающая сторона должна вызвать его метод *Stmt.Close.

Указанный контекст используется для подготовки оператора, а не для его выполнения.

func (*Conn) QueryContext 1.9

func (c *Conn) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)

QueryContext выполняет запрос, возвращающий строки, обычно SELECT. Аргументы используются для параметров-заполнителей в запросе.

func (*Conn) QueryRowContext 1.9

func (c *Conn) QueryRowContext(ctx context.Context, query string, args ...any) *Row

QueryRowContext выполняет запрос, который должен вернуть не более одной строки. QueryRowContext всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода *Row.Scan. Если запрос не выбирает ни одной строки, *Row.Scan вернёт ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.

func (*Conn) Raw 1.13

func (c *Conn) Raw(f func(driverConn any) error) (err error)

Raw выполняет f, предоставляя доступ к базовому соединению драйвера на время выполнения f. driverConn нельзя использовать вне f.

После возврата f, если err не равен driver.ErrBadConn, Conn останется доступным для использования до вызова Conn.Close.

type DB

DB — это дескриптор базы данных, представляющий пул из нуля или более базовых соединений. Его безопасно использовать параллельно из нескольких горутин.

Пакет sql автоматически создаёт и освобождает соединения, а также поддерживает пул свободных неактивных соединений. Если в базе данных предусмотрено состояние на уровне соединения, за таким состоянием можно надёжно наблюдать в рамках транзакции (Tx) или соединения (Conn). После вызова DB.Begin возвращённый Tx привязывается к одному соединению. После вызова Tx.Commit или Tx.Rollback для транзакции её соединение возвращается в пул неактивных соединений DB. Размер пула можно настроить с помощью DB.SetMaxIdleConns.

type DB struct {
    // contains filtered or unexported fields
}

func Open

func Open(driverName, dataSourceName string) (*DB, error)

Open открывает базу данных, указанную именем драйвера базы данных и специфичным для драйвера именем источника данных, обычно включающим как минимум имя базы данных и сведения о соединении.

Большинство пользователей открывают базу данных с помощью специфичной для драйвера вспомогательной функции подключения, возвращающей *DB. Стандартная библиотека Go не включает драйверы баз данных. Список сторонних драйверов см. по адресу https://golang.org/s/sqldrivers.

Open может только проверять аргументы, не создавая соединение с базой данных. Чтобы проверить корректность имени источника данных, вызовите DB.Ping.

Возвращённый DB безопасно использовать параллельно из нескольких горутин; он поддерживает собственный пул неактивных соединений. Поэтому функцию Open следует вызывать только один раз. Закрывать DB обычно не требуется.

func OpenDB 1.10

func OpenDB(c driver.Connector) *DB

OpenDB открывает базу данных с помощью driver.Connector, позволяя драйверам обходиться без строкового имени источника данных.

Большинство пользователей открывают базу данных с помощью специфичной для драйвера вспомогательной функции подключения, возвращающей *DB. Стандартная библиотека Go не включает драйверы баз данных. Список сторонних драйверов см. по адресу https://golang.org/s/sqldrivers.

OpenDB может только проверять аргументы, не создавая соединение с базой данных. Чтобы проверить корректность имени источника данных, вызовите DB.Ping.

Возвращённый DB безопасно использовать параллельно из нескольких горутин; он поддерживает собственный пул неактивных соединений. Поэтому функцию OpenDB следует вызывать только один раз. Закрывать DB обычно не требуется.

func (*DB) Begin

func (db *DB) Begin() (*Tx, error)

Begin начинает транзакцию. Уровень изоляции по умолчанию зависит от драйвера.

Внутри Begin использует context.Background; чтобы указать контекст, используйте DB.BeginTx.

func (*DB) BeginTx 1.8

func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error)

BeginTx начинает транзакцию.

Указанный контекст используется до фиксации или отката транзакции. Если контекст отменён, пакет sql выполнит откат транзакции. Tx.Commit вернёт ошибку, если контекст, переданный в BeginTx, отменён.

Указанный TxOptions является необязательным и может быть nil, если следует использовать значения по умолчанию. Если используется уровень изоляции, отличный от стандартного, который драйвер не поддерживает, будет возвращена ошибка.

Пример

Код:

tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
if err != nil {
    log.Fatal(err)
}
id := 37
_, execErr := tx.Exec(`UPDATE users SET status = ? WHERE id = ?`, "paid", id)
if execErr != nil {
    _ = tx.Rollback()
    log.Fatal(execErr)
}
if err := tx.Commit(); err != nil {
    log.Fatal(err)
}

func (*DB) Close

func (db *DB) Close() error

Close закрывает базу данных и запрещает запуск новых запросов. Затем Close ожидает завершения всех запросов, обработка которых уже началась на сервере.

Закрывать DB обычно не нужно, поскольку дескриптор DB предназначен для длительного использования и совместного доступа из множества горутин.

func (*DB) Conn 1.9

func (db *DB) Conn(ctx context.Context) (*Conn, error)

Conn возвращает одно соединение: либо открывает новое, либо извлекает существующее из пула соединений. Conn будет заблокирован до возврата соединения или отмены ctx. Запросы, выполняемые через один и тот же Conn, будут выполняться в одном сеансе базы данных.

После использования каждое Conn необходимо вернуть в пул базы данных, вызвав Conn.Close.

func (*DB) Driver

func (db *DB) Driver() driver.Driver

Driver возвращает базовый драйвер базы данных.

func (*DB) Exec

func (db *DB) Exec(query string, args ...any) (Result, error)

Exec выполняет запрос, не возвращая строк. Аргументы предназначены для параметров-заполнителей в запросе.

Exec использует внутри context.Background; чтобы указать контекст, используйте DB.ExecContext.

func (*DB) ExecContext 1.8

func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (Result, error)

ExecContext выполняет запрос, не возвращая строк. Аргументы предназначены для параметров-заполнителей в запросе.

Пример

Код:

id := 47
result, err := db.ExecContext(ctx, "UPDATE balances SET balance = balance + 10 WHERE user_id = ?", id)
if err != nil {
    log.Fatal(err)
}
rows, err := result.RowsAffected()
if err != nil {
    log.Fatal(err)
}
if rows != 1 {
    log.Fatalf("expected to affect 1 row, affected %d", rows)
}

func (*DB) Ping 1.1

func (db *DB) Ping() error

Ping проверяет, остается ли подключение к базе данных активным, устанавливая его при необходимости.

Ping использует внутри context.Background; чтобы указать контекст, используйте DB.PingContext.

func (*DB) PingContext 1.8

func (db *DB) PingContext(ctx context.Context) error

PingContext проверяет, остается ли подключение к базе данных активным, устанавливая его при необходимости.

Пример

Код:

// Ping and PingContext may be used to determine if communication with
// the database server is still possible.
//
// When used in a command line application Ping may be used to establish
// that further queries are possible; that the provided DSN is valid.
//
// When used in long running service Ping may be part of the health
// checking system.

ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()

status := "up"
if err := db.PingContext(ctx); err != nil {
    status = "down"
}
log.Println(status)

func (*DB) Prepare

func (db *DB) Prepare(query string) (*Stmt, error)

Prepare создает подготовленную инструкцию для последующих запросов или операций. Из возвращенной инструкции можно одновременно выполнять несколько запросов или операций. Когда инструкция больше не нужна, вызывающий код должен вызвать ее метод *Stmt.Close.

Prepare использует внутри context.Background; чтобы указать контекст, используйте DB.PrepareContext.

Пример

Код:

projects := []struct {
    mascot  string
    release int
}{
    {"tux", 1991},
    {"duke", 1996},
    {"gopher", 2009},
    {"moby dock", 2013},
}

stmt, err := db.Prepare("INSERT INTO projects(id, mascot, release, category) VALUES( ?, ?, ?, ? )")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close() // Prepared statements take up server resources and should be closed after use.

for id, project := range projects {
    if _, err := stmt.Exec(id+1, project.mascot, project.release, "open source"); err != nil {
        log.Fatal(err)
    }
}

func (*DB) PrepareContext 1.8

func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error)

PrepareContext создает подготовленную инструкцию для последующих запросов или операций. Из возвращенной инструкции можно одновременно выполнять несколько запросов или операций. Когда инструкция больше не нужна, вызывающий код должен вызвать ее метод *Stmt.Close.

Переданный контекст используется при подготовке инструкции, а не при ее выполнении.

func (*DB) Query

func (db *DB) Query(query string, args ...any) (*Rows, error)

Query выполняет запрос, возвращающий строки, обычно SELECT. Аргументы предназначены для параметров-заполнителей в запросе.

Query использует внутри context.Background; чтобы указать контекст, используйте DB.QueryContext.

Пример (несколько наборов результатов)

Код:

age := 27
q := `
create temp table uid (id bigint); -- Create temp table for queries.
insert into uid
select id from users where age < ?; -- Populate temp table.

-- First result set.
select
    users.id, name
from
    users
    join uid on users.id = uid.id
;

-- Second result set.
select 
    ur.user, ur.role
from
    user_roles as ur
    join uid on uid.id = ur.user
;
    `
rows, err := db.Query(q, age)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

for rows.Next() {
    var (
        id   int64
        name string
    )
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    log.Printf("id %d name is %s\n", id, name)
}
if !rows.NextResultSet() {
    log.Fatalf("expected more result sets: %v", rows.Err())
}
var roleMap = map[int64]string{
    1: "user",
    2: "admin",
    3: "gopher",
}
for rows.Next() {
    var (
        id   int64
        role int64
    )
    if err := rows.Scan(&id, &role); err != nil {
        log.Fatal(err)
    }
    log.Printf("id %d has role %s\n", id, roleMap[role])
}
if err := rows.Err(); err != nil {
    log.Fatal(err)
}

func (*DB) QueryContext 1.8

func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)

QueryContext выполняет запрос, возвращающий строки, обычно SELECT. Аргументы предназначены для параметров-заполнителей в запросе.

Пример

Код:

age := 27
rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age=?", age)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()
names := make([]string, 0)

for rows.Next() {
    var name string
    if err := rows.Scan(&name); err != nil {
        // Check for a scan error.
        // Query rows will be closed with defer.
        log.Fatal(err)
    }
    names = append(names, name)
}
// If the database is being written to ensure to check for Close
// errors that may be returned from the driver. The query may
// encounter an auto-commit error and be forced to rollback changes.
rerr := rows.Close()
if rerr != nil {
    log.Fatal(rerr)
}

// Rows.Err will report the last error encountered by Rows.Scan.
if err := rows.Err(); err != nil {
    log.Fatal(err)
}
fmt.Printf("%s are %d years old", strings.Join(names, ", "), age)

func (*DB) QueryRow

func (db *DB) QueryRow(query string, args ...any) *Row

QueryRow выполняет запрос, который, как ожидается, вернет не более одной строки. QueryRow всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода Scan у Row. Если запрос не выбирает ни одной строки, *Row.Scan вернет ErrNoRows. В противном случае *Row.Scan считывает первую выбранную строку, а остальные отбрасывает.

QueryRow использует внутри context.Background; чтобы указать контекст, используйте DB.QueryRowContext.

func (*DB) QueryRowContext 1.8

func (db *DB) QueryRowContext(ctx context.Context, query string, args ...any) *Row

QueryRowContext выполняет запрос, который, как ожидается, вернет не более одной строки. QueryRowContext всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода Scan у Row. Если запрос не выбирает ни одной строки, *Row.Scan вернет ErrNoRows. В противном случае *Row.Scan считывает первую выбранную строку, а остальные отбрасывает.

Пример

Код:

id := 123
var username string
var created time.Time
err := db.QueryRowContext(ctx, "SELECT username, created_at FROM users WHERE id=?", id).Scan(&username, &created)
switch {
case err == sql.ErrNoRows:
    log.Printf("no user with id %d\n", id)
case err != nil:
    log.Fatalf("query error: %v\n", err)
default:
    log.Printf("username is %q, account created on %s\n", username, created)
}

func (*DB) SetConnMaxIdleTime 1.15

func (db *DB) SetConnMaxIdleTime(d time.Duration)

SetConnMaxIdleTime задает максимальное время простоя подключения.

Просроченные подключения могут быть закрыты при первой возможности перед повторным использованием.

Если d <= 0, подключения не закрываются из-за времени простоя.

func (*DB) SetConnMaxLifetime 1.6

func (db *DB) SetConnMaxLifetime(d time.Duration)

SetConnMaxLifetime задает максимальное время, в течение которого можно повторно использовать подключение.

Просроченные подключения могут быть закрыты при первой возможности перед повторным использованием.

Если d <= 0, подключения не закрываются из-за срока их существования.

func (*DB) SetMaxIdleConns 1.1

func (db *DB) SetMaxIdleConns(n int)

SetMaxIdleConns задает максимальное количество подключений в пуле неактивных подключений.

Если MaxOpenConns больше 0, но меньше нового значения MaxIdleConns, новое значение MaxIdleConns будет уменьшено до ограничения MaxOpenConns.

Если n <= 0, неактивные подключения не сохраняются.

В настоящее время максимальное количество неактивных подключений по умолчанию равно 2. В будущих версиях это значение может измениться.

func (*DB) SetMaxOpenConns 1.2

func (db *DB) SetMaxOpenConns(n int)

SetMaxOpenConns задает максимальное количество открытых подключений к базе данных.

Если MaxIdleConns больше 0, а новое значение MaxOpenConns меньше MaxIdleConns, MaxIdleConns будет уменьшено до нового ограничения MaxOpenConns.

Если n <= 0, количество открытых подключений не ограничено. Значение по умолчанию — 0 (без ограничений).

func (*DB) Stats 1.5

func (db *DB) Stats() DBStats

Stats возвращает статистику базы данных.

type DBStats 1.5

DBStats содержит статистику базы данных.

type DBStats struct {
    MaxOpenConnections int // Maximum number of open connections to the database; added in Go 1.11

    // Pool Status
    OpenConnections int // The number of established connections both in use and idle.
    InUse           int // The number of connections currently in use; added in Go 1.11
    Idle            int // The number of idle connections; added in Go 1.11

    // Counters
    WaitCount         int64         // The total number of connections waited for; added in Go 1.11
    WaitDuration      time.Duration // The total time blocked waiting for a new connection; added in Go 1.11
    MaxIdleClosed     int64         // The total number of connections closed due to SetMaxIdleConns; added in Go 1.11
    MaxIdleTimeClosed int64         // The total number of connections closed due to SetConnMaxIdleTime; added in Go 1.15
    MaxLifetimeClosed int64         // The total number of connections closed due to SetConnMaxLifetime; added in Go 1.11
}

type IsolationLevel 1.8

IsolationLevel — это уровень изоляции транзакции, используемый в TxOptions.

type IsolationLevel int

Различные уровни изоляции, которые драйверы могут поддерживать в DB.BeginTx. Если драйвер не поддерживает указанный уровень изоляции, может быть возвращена ошибка.

См. https://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels.

const (
    LevelDefault IsolationLevel = iota
    LevelReadUncommitted
    LevelReadCommitted
    LevelWriteCommitted
    LevelRepeatableRead
    LevelSnapshot
    LevelSerializable
    LevelLinearizable
)

func (IsolationLevel) String 1.11

func (i IsolationLevel) String() string

String возвращает название уровня изоляции транзакции.

type NamedArg 1.8

NamedArg — это именованный аргумент. Значения NamedArg можно использовать в качестве аргументов для DB.Query или DB.Exec; они связываются с соответствующим именованным параметром в SQL-операторе.

Более краткий способ создания значений NamedArg см. в функции Named.

type NamedArg struct {

    // Name is the name of the parameter placeholder.
    //
    // If empty, the ordinal position in the argument list will be
    // used.
    //
    // Name must omit any symbol prefix.
    Name string

    // Value is the value of the parameter.
    // It may be assigned the same value types as the query
    // arguments.
    Value any
    // contains filtered or unexported fields
}

func Named 1.8

func Named(name string, value any) NamedArg

Named предоставляет более краткий способ создания значений NamedArg.

Пример использования:

db.ExecContext(ctx, `
    delete from Invoice
    where
        TimeCreated < @end
        and TimeCreated >= @start;`,
    sql.Named("start", startTime),
    sql.Named("end", endTime),
)

type Null

Null представляет значение, которое может быть null. Null реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования:

var s Null[string]
err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
   // use s.V
} else {
   // NULL value
}

T должен быть одним из типов, допустимых для driver.Value.

type Null[T any] struct {
    V     T
    Valid bool
}

func (*Null[T]) Scan

func (n *Null[T]) Scan(value any) error

func (Null[T]) Value

func (n Null[T]) Value() (driver.Value, error)

type NullBool

NullBool представляет значение bool, которое может быть null. NullBool реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullBool struct {
    Bool  bool
    Valid bool // Valid is true if Bool is not NULL
}

func (*NullBool) Scan

func (n *NullBool) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullBool) Value

func (n NullBool) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullByte 1.17

NullByte представляет значение byte, которое может быть null. NullByte реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullByte struct {
    Byte  byte
    Valid bool // Valid is true if Byte is not NULL
}

func (*NullByte) Scan 1.17

func (n *NullByte) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullByte) Value 1.17

func (n NullByte) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullFloat64

NullFloat64 представляет значение float64, которое может быть null. NullFloat64 реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullFloat64 struct {
    Float64 float64
    Valid   bool // Valid is true if Float64 is not NULL
}

func (*NullFloat64) Scan

func (n *NullFloat64) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullFloat64) Value

func (n NullFloat64) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullInt16 1.17

NullInt16 представляет значение int16, которое может быть null. NullInt16 реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullInt16 struct {
    Int16 int16
    Valid bool // Valid is true if Int16 is not NULL
}

func (*NullInt16) Scan 1.17

func (n *NullInt16) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullInt16) Value 1.17

func (n NullInt16) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullInt32 1.13

NullInt32 представляет значение int32, которое может быть null. NullInt32 реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullInt32 struct {
    Int32 int32
    Valid bool // Valid is true if Int32 is not NULL
}

func (*NullInt32) Scan 1.13

func (n *NullInt32) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullInt32) Value 1.13

func (n NullInt32) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullInt64

NullInt64 представляет значение int64, которое может быть null. NullInt64 реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullInt64 struct {
    Int64 int64
    Valid bool // Valid is true if Int64 is not NULL
}

func (*NullInt64) Scan

func (n *NullInt64) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullInt64) Value

func (n NullInt64) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullString

NullString представляет строку, которая может быть null. NullString реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования:

var s NullString
err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
   // use s.String
} else {
   // NULL value
}
type NullString struct {
    String string
    Valid  bool // Valid is true if String is not NULL
}

func (*NullString) Scan

func (ns *NullString) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullString) Value

func (ns NullString) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type NullTime 1.13

NullTime представляет значение time.Time, которое может быть null. NullTime реализует интерфейс Scanner, поэтому его можно использовать в качестве цели сканирования, как и NullString.

type NullTime struct {
    Time  time.Time
    Valid bool // Valid is true if Time is not NULL
}

func (*NullTime) Scan 1.13

func (n *NullTime) Scan(value any) error

Scan реализует интерфейс Scanner.

func (NullTime) Value 1.13

func (n NullTime) Value() (driver.Value, error)

Value реализует интерфейс driver.Valuer.

type Out 1.9

Out можно использовать для получения выходных параметров OUTPUT из хранимых процедур.

Не все драйверы и базы данных поддерживают выходные параметры OUTPUT.

Пример использования:

var outArg string
_, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", sql.Out{Dest: &outArg}))
type Out struct {

    // Dest is a pointer to the value that will be set to the result of the
    // stored procedure's OUTPUT parameter.
    Dest any

    // In is whether the parameter is an INOUT parameter. If so, the input value to the stored
    // procedure is the dereferenced value of Dest's pointer, which is then replaced with
    // the output value.
    In bool
    // contains filtered or unexported fields
}

type RawBytes

RawBytes — это срез байтов, содержащий ссылку на память, которой владеет сама база данных. После вызова Rows.Scan для RawBytes срез действителен только до следующего вызова Rows.Next, Rows.Scan или Rows.Close.

type RawBytes []byte

type Result

Result содержит сведения о выполненной SQL-команде.

type Result interface {
    // LastInsertId returns the integer generated by the database
    // in response to a command. Typically this will be from an
    // "auto increment" column when inserting a new row. Not all
    // databases support this feature, and the syntax of such
    // statements varies.
    LastInsertId() (int64, error)

    // RowsAffected returns the number of rows affected by an
    // update, insert, or delete. Not every database or database
    // driver may support this.
    RowsAffected() (int64, error)
}

type Row

Row — это результат вызова DB.QueryRow для выбора одной строки.

type Row struct {
    // contains filtered or unexported fields
}

func (*Row) Err 1.15

func (r *Row) Err() error

Err позволяет обёрточным пакетам проверять наличие ошибок запроса без вызова Row.Scan. Err возвращает ошибку, если она возникла при выполнении запроса. Если эта ошибка не равна nil, она также будет возвращена вызовом Row.Scan.

func (*Row) Scan

func (r *Row) Scan(dest ...any) error

Scan копирует столбцы из найденной строки в значения, на которые указывают dest. Подробности см. в документации по Rows.Scan. Если запросу соответствует более одной строки, Scan использует первую строку, а остальные отбрасывает. Если запросу не соответствует ни одна строка, Scan возвращает ErrNoRows.

type Rows

Rows — результат запроса. Его курсор находится перед первой строкой набора результатов. Используйте Rows.Next, чтобы переходить от строки к строке.

type Rows struct {
    // contains filtered or unexported fields
}

Пример

Код:

age := 27
rows, err := db.QueryContext(ctx, "SELECT name FROM users WHERE age=?", age)
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

names := make([]string, 0)
for rows.Next() {
    var name string
    if err := rows.Scan(&name); err != nil {
        log.Fatal(err)
    }
    names = append(names, name)
}
// Check for errors from iterating over rows.
if err := rows.Err(); err != nil {
    log.Fatal(err)
}
log.Printf("%s are %d years old", strings.Join(names, ", "), age)

func (*Rows) Close

func (rs *Rows) Close() error

Close закрывает Rows, предотвращая дальнейший перебор. Если вызов Rows.Next возвращает false и других наборов результатов нет, Rows закрывается автоматически, и достаточно проверить результат Rows.Err. Close идемпотентен и не влияет на результат Rows.Err.

func (*Rows) ColumnTypes 1.8

func (rs *Rows) ColumnTypes() ([]*ColumnType, error)

ColumnTypes возвращает информацию о столбцах, например тип столбца, его длину и возможность содержать значение NULL. Некоторые драйверы могут не предоставлять часть этой информации.

func (*Rows) Columns

func (rs *Rows) Columns() ([]string, error)

Columns возвращает имена столбцов. Columns возвращает ошибку, если строки закрыты.

func (*Rows) Err

func (rs *Rows) Err() error

Err возвращает ошибку, если она возникла во время перебора. Err можно вызвать после явного или неявного вызова Rows.Close.

func (*Rows) Next

func (rs *Rows) Next() bool

Next подготавливает следующую строку результата для чтения методом Rows.Scan. Он возвращает true в случае успеха или false, если следующей строки результата нет либо при её подготовке произошла ошибка. Чтобы различить эти случаи, следует проверить Rows.Err.

Каждому вызову Rows.Scan, даже первому, должен предшествовать вызов Rows.Next.

func (*Rows) NextResultSet 1.8

func (rs *Rows) NextResultSet() bool

NextResultSet подготавливает следующий набор результатов для чтения. Метод сообщает, есть ли следующие наборы результатов; он возвращает false, если следующего набора результатов нет или при переходе к нему произошла ошибка. Чтобы различить эти случаи, следует проверить метод Rows.Err.

После вызова NextResultSet перед сканированием всегда следует вызывать метод Rows.Next. В следующих наборах результатов могут отсутствовать строки.

func (*Rows) Scan

func (rs *Rows) Scan(dest ...any) error

Scan копирует столбцы текущей строки в значения, на которые указывают dest. Число значений в dest должно совпадать с числом столбцов в Rows.

Scan преобразует прочитанные из базы данных столбцы в следующие стандартные типы Go и специальные типы, предоставляемые пакетом sql:

*string
*[]byte
*int, *int8, *int16, *int32, *int64
*uint, *uint8, *uint16, *uint32, *uint64
*bool
*float32, *float64
*interface{}
*RawBytes
*Rows (cursor value)
any type implementing Scanner (see Scanner docs)

В самом простом случае, если значение исходного столбца имеет целочисленный тип, тип bool или строковый тип T, а dest имеет тип *T, Scan просто присваивает значение через указатель.

Scan также преобразует строковые и числовые типы, если при этом не теряется информация. Scan преобразует все числа, прочитанные из числовых столбцов базы данных, в строки типа *string, а при сканировании в числовые типы проверяет переполнение. Например, float64 со значением 300 или строку со значением "300" можно сканировать в uint16, но не в uint8, тогда как float64(255) или "255" можно сканировать в uint8. Исключение: при преобразовании некоторых значений float64 в строки может теряться информация. В общем случае сканируйте столбцы с числами с плавающей точкой в *float64.

Если аргумент dest имеет тип *[]byte, Scan сохраняет в этом аргументе копию соответствующих данных. Копия принадлежит вызывающему коду, поэтому её можно изменять и хранить неограниченно долго. Копии можно избежать, используя вместо этого аргумент типа *RawBytes; ограничения на его использование описаны в документации по RawBytes.

Если аргумент имеет тип *interface{}, Scan копирует значение, предоставленное базовым драйвером, без преобразования. При сканировании исходного значения типа []byte в *interface{} создаётся копия среза, которая принадлежит вызывающему коду.

Исходные значения типа time.Time можно сканировать в значения типов *time.Time, *interface{}, *string или *[]byte. При преобразовании в два последних типа используется time.RFC3339Nano.

Исходные значения типа bool можно сканировать в типы *bool, *interface{}, *string, *[]byte или *RawBytes.

При сканировании в *bool исходное значение может быть true, false, 1, 0 или строкой, которую можно разобрать с помощью strconv.ParseBool.

Scan также может преобразовать курсор, возвращённый запросом, например "select cursor(select * from my_table) from dual", в значение типа *Rows, из которого затем можно выполнять сканирование. Родительский запрос select закроет любой курсор *Rows, если родительский *Rows будет закрыт.

Если любой из первых аргументов, реализующих интерфейс Scanner, возвращает ошибку, эта ошибка будет обёрнута в возвращаемую ошибку.

type Scanner

Scanner — интерфейс, используемый методом Rows.Scan.

type Scanner interface {
    // Scan assigns a value from a database driver.
    //
    // The src value will be of one of the following types:
    //
    //    int64
    //    float64
    //    bool
    //    []byte
    //    string
    //    time.Time
    //    nil - for NULL values
    //
    // An error should be returned if the value cannot be stored
    // without loss of information.
    //
    // Reference types such as []byte are only valid until the next call to Scan
    // and should not be retained. Their underlying memory is owned by the driver.
    // If retention is necessary, copy their values before the next call to Scan.
    Scan(src any) error
}

type Stmt

Stmt — подготовленный оператор. Stmt безопасно использовать одновременно из нескольких горутин.

Если Stmt подготовлен для Tx или Conn, он навсегда привязывается к одному базовому соединению. Если Tx или Conn закрывается, Stmt становится непригодным для использования, и все операции возвращают ошибку. Если Stmt подготовлен для DB, он остаётся доступным в течение всего срока существования DB. Когда для выполнения Stmt потребуется новое базовое соединение, он автоматически подготовится на новом соединении.

type Stmt struct {
    // contains filtered or unexported fields
}

Пример

Код:

// In normal use, create one Stmt when your process starts.
stmt, err := db.PrepareContext(ctx, "SELECT username FROM users WHERE id = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

// Then reuse it each time you need to issue the query.
id := 43
var username string
err = stmt.QueryRowContext(ctx, id).Scan(&username)
switch {
case err == sql.ErrNoRows:
    log.Fatalf("no user with id %d", id)
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 1.8

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 1.8

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 1.8

func (s *Stmt) QueryRowContext(ctx context.Context, args ...any) *Row

QueryRowContext выполняет подготовленный оператор запроса с заданными аргументами. Если во время выполнения оператора возникает ошибка, она будет возвращена при вызове Scan для возвращённого *Row, который всегда не равен nil. Если запрос не выбирает ни одной строки, *Row.Scan вернёт ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.

Пример

Код:

// In normal use, create one Stmt when your process starts.
stmt, err := db.PrepareContext(ctx, "SELECT username FROM users WHERE id = ?")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close()

// Then reuse it each time you need to issue the query.
id := 43
var username string
err = stmt.QueryRowContext(ctx, id).Scan(&username)
switch {
case err == sql.ErrNoRows:
    log.Fatalf("no user with id %d", id)
case err != nil:
    log.Fatal(err)
default:
    log.Printf("username is %s\n", username)
}

type Tx

Tx — это выполняющаяся транзакция базы данных.

Транзакция должна завершаться вызовом Tx.Commit или Tx.Rollback.

После вызова Tx.Commit или Tx.Rollback все операции с транзакцией завершаются ошибкой ErrTxDone.

Операторы, подготовленные для транзакции вызовом методов Tx.Prepare или Tx.Stmt этой транзакции, закрываются при вызове Tx.Commit или Tx.Rollback.

type Tx struct {
    // contains filtered or unexported fields
}

func (*Tx) Commit

func (tx *Tx) Commit() error

Commit фиксирует транзакцию.

func (*Tx) Exec

func (tx *Tx) Exec(query string, args ...any) (Result, error)

Exec выполняет запрос, который не возвращает строки. Например, INSERT или UPDATE.

Exec использует внутри context.Background; чтобы указать контекст, используйте Tx.ExecContext.

func (*Tx) ExecContext 1.8

func (tx *Tx) ExecContext(ctx context.Context, query string, args ...any) (Result, error)

ExecContext выполняет запрос, который не возвращает строки. Например, INSERT или UPDATE.

Пример

Код:

tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
if err != nil {
    log.Fatal(err)
}
id := 37
_, execErr := tx.ExecContext(ctx, "UPDATE users SET status = ? WHERE id = ?", "paid", id)
if execErr != nil {
    if rollbackErr := tx.Rollback(); rollbackErr != nil {
        log.Fatalf("update failed: %v, unable to rollback: %v\n", execErr, rollbackErr)
    }
    log.Fatalf("update failed: %v", execErr)
}
if err := tx.Commit(); err != nil {
    log.Fatal(err)
}

func (*Tx) Prepare

func (tx *Tx) Prepare(query string) (*Stmt, error)

Prepare создаёт подготовленный оператор для использования в транзакции.

Возвращённый оператор работает в рамках транзакции и будет закрыт после фиксации или отката транзакции.

Чтобы использовать в этой транзакции существующий подготовленный оператор, см. Tx.Stmt.

Prepare использует внутри context.Background; чтобы указать контекст, используйте Tx.PrepareContext.

Пример

Код:

projects := []struct {
    mascot  string
    release int
}{
    {"tux", 1991},
    {"duke", 1996},
    {"gopher", 2009},
    {"moby dock", 2013},
}

tx, err := db.Begin()
if err != nil {
    log.Fatal(err)
}
defer tx.Rollback() // The rollback will be ignored if the tx has been committed later in the function.

stmt, err := tx.Prepare("INSERT INTO projects(id, mascot, release, category) VALUES( ?, ?, ?, ? )")
if err != nil {
    log.Fatal(err)
}
defer stmt.Close() // Prepared statements take up server resources and should be closed after use.

for id, project := range projects {
    if _, err := stmt.Exec(id+1, project.mascot, project.release, "open source"); err != nil {
        log.Fatal(err)
    }
}
if err := tx.Commit(); err != nil {
    log.Fatal(err)
}

func (*Tx) PrepareContext 1.8

func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error)

PrepareContext создаёт подготовленный оператор для использования в транзакции.

Возвращённый оператор работает в рамках транзакции и будет закрыт после фиксации или отката транзакции.

Чтобы использовать в этой транзакции существующий подготовленный оператор, см. Tx.Stmt.

Переданный контекст будет использоваться для подготовки контекста, а не для выполнения возвращённого оператора. Возвращённый оператор будет выполняться в контексте транзакции.

func (*Tx) Query

func (tx *Tx) Query(query string, args ...any) (*Rows, error)

Query выполняет запрос, возвращающий строки, обычно SELECT.

Query использует внутри context.Background; чтобы указать контекст, используйте Tx.QueryContext.

func (*Tx) QueryContext 1.8

func (tx *Tx) QueryContext(ctx context.Context, query string, args ...any) (*Rows, error)

QueryContext выполняет запрос, возвращающий строки, обычно SELECT.

func (*Tx) QueryRow

func (tx *Tx) QueryRow(query string, args ...any) *Row

QueryRow выполняет запрос, который должен вернуть не более одной строки. QueryRow всегда возвращает значение, не равное nil. Ошибки откладываются до вызова метода Scan у Row. Если запрос не выбирает ни одной строки, *Row.Scan вернёт ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.

QueryRow использует внутри context.Background; чтобы указать контекст, используйте Tx.QueryRowContext.

func (*Tx) QueryRowContext 1.8

func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...any) *Row

QueryRowContext выполняет запрос, который должен вернуть не более одной строки. QueryRowContext всегда возвращает значение, не равное nil. Ошибки откладываются до вызова метода Scan у Row. Если запрос не выбирает ни одной строки, *Row.Scan вернёт ErrNoRows. В противном случае *Row.Scan сканирует первую выбранную строку и отбрасывает остальные.

func (*Tx) Rollback

func (tx *Tx) Rollback() error

Rollback прерывает транзакцию.

Пример

Код:

tx, err := db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable})
if err != nil {
    log.Fatal(err)
}
id := 53
_, err = tx.ExecContext(ctx, "UPDATE drivers SET status = ? WHERE id = ?;", "assigned", id)
if err != nil {
    if rollbackErr := tx.Rollback(); rollbackErr != nil {
        log.Fatalf("update drivers: unable to rollback: %v", rollbackErr)
    }
    log.Fatal(err)
}
_, err = tx.ExecContext(ctx, "UPDATE pickups SET driver_id = $1;", id)
if err != nil {
    if rollbackErr := tx.Rollback(); rollbackErr != nil {
        log.Fatalf("update failed: %v, unable to back: %v", err, rollbackErr)
    }
    log.Fatal(err)
}
if err := tx.Commit(); err != nil {
    log.Fatal(err)
}

func (*Tx) Stmt

func (tx *Tx) Stmt(stmt *Stmt) *Stmt

Stmt возвращает подготовленный оператор, привязанный к транзакции, на основе существующего оператора.

Пример:

updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
...
tx, err := db.Begin()
...
res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)

Возвращённый оператор работает в рамках транзакции и будет закрыт после фиксации или отката транзакции.

Stmt использует внутри context.Background; чтобы указать контекст, используйте Tx.StmtContext.

func (*Tx) StmtContext 1.8

func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt

StmtContext возвращает подготовленный оператор, привязанный к транзакции, на основе существующего оператора.

Пример:

updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
...
tx, err := db.Begin()
...
res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203)

Переданный контекст используется для подготовки оператора, а не для его выполнения.

Возвращённый оператор работает в рамках транзакции и будет закрыт после фиксации или отката транзакции.

type TxOptions 1.8

TxOptions содержит параметры транзакции, которые будут использоваться в DB.BeginTx.

type TxOptions struct {
    // Isolation is the transaction isolation level.
    // If zero, the driver or database's default level is used.
    Isolation IsolationLevel
    ReadOnly  bool
}

Подкаталоги

Имя Краткое описание
..
driver Пакет driver определяет интерфейсы, которые должны реализовывать драйверы баз данных, используемые пакетом sql.

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/database/sql/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API