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 Drivers() []string
  • func Register(name string, driver driver.Driver)
  • тип 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
  • тип 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)
  • тип 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
  • тип DBStats
  • тип IsolationLevel
  • func (i IsolationLevel) String() string
  • тип NamedArg
  • func Named(name string, value any) NamedArg
  • тип Null
  • func (n *Null[T]) Scan(value any) error
  • func (n Null[T]) Value() (driver.Value, error)
  • тип NullBool
  • func (n *NullBool) Scan(value any) error
  • func (n NullBool) Value() (driver.Value, error)
  • тип NullByte
  • func (n *NullByte) Scan(value any) error
  • func (n NullByte) Value() (driver.Value, error)
  • тип NullFloat64
  • func (n *NullFloat64) Scan(value any) error
  • func (n NullFloat64) Value() (driver.Value, error)
  • тип NullInt16
  • func (n *NullInt16) Scan(value any) error
  • func (n NullInt16) Value() (driver.Value, error)
  • тип NullInt32
  • func (n *NullInt32) Scan(value any) error
  • func (n NullInt32) Value() (driver.Value, error)
  • тип NullInt64
  • func (n *NullInt64) Scan(value any) error
  • func (n NullInt64) Value() (driver.Value, error)
  • тип NullString
  • func (ns *NullString) Scan(value any) error
  • func (ns NullString) Value() (driver.Value, error)
  • тип NullTime
  • func (n *NullTime) Scan(value any) error
  • func (n NullTime) Value() (driver.Value, error)
  • тип Out
  • тип RawBytes
  • тип Result
  • тип Row
  • func (r *Row) Err() error
  • func (r *Row) Scan(dest ...any) error
  • тип 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
  • тип Scanner
  • тип 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
  • тип 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
  • тип 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
Пакет (OpenDBCLI)
Пакет (OpenDBService)

Файлы пакета

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 Drivers 1.4

func Drivers() []string

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

func Register

func Register(name string, driver driver.Driver)

Register делает доступным драйвер базы данных под указанным именем. Если Register вызывается дважды с одинаковым именем или если драйвер равен 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 должен вызвать 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. ДрайверConn не должен использоваться за пределами 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

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

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.

Пример (MultipleResultSets)

Код:

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 всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода Row's Scan. Если запрос не выбирает ни одной строки, *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 всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода Row's Scan. Если запрос не выбирает ни одной строки, the *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 реализует интерфейс 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
}
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 представляет булево значение, которое может быть нулевым. 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 представляет байт, который может быть нулевым. 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, который может быть нулевым. 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, который может быть нулевым. 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, который может быть нулевым. 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.

тип NullInt64

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

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

функция (*NullInt64) Scan

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

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

функция (NullInt64) Value

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

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

тип NullString

NullString представляет собой строку, которая может быть нулевой. 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
}

функция (*NullString) Scan

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

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

функция (NullString) Value

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

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

тип NullTime 1.13

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

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

функция (*NullTime) Scan 1.13

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

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

функция (NullTime) Value 1.13

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

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

тип Out 1.9

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

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

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

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
}

тип RawBytes

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

type RawBytes []byte

тип 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)
}

тип Row

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

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

функция (*Row) Err 1.15

func (r *Row) Err() error

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

функция (*Row) Scan

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

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

тип 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)

функция (*Rows) Close

func (rs *Rows) Close() error

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

функция (*Rows) ColumnTypes 1.8

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

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

функция (*Rows) Columns

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

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

функция (*Rows) Err

func (rs *Rows) Err() error

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

функция (*Rows) Next

func (rs *Rows) Next() bool

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

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

функция (*Rows) NextResultSet 1.8

func (rs *Rows) NextResultSet() bool

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

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

функция (*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)

В самом простом случае, если тип значения из исходного столбца — целое число, логическое значение или строковый тип 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, возвращает ошибку, эта ошибка будет обернута в возвращаемую ошибку.

тип 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
}

тип 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)
}

функция (*Stmt) Close

func (s *Stmt) Close() error

Close закрывает утверждение.

функция (*Stmt) Exec

func (s *Stmt) Exec(args ...any) (Result, error)

Exec выполняет подготовленное утверждение с заданными аргументами и возвращает Result, обобщающий эффект утверждения.

Exec использует context.Background внутри; для указания контекста используйте Stmt.ExecContext.

функция (*Stmt) ExecContext 1.8

func (s *Stmt) ExecContext(ctx context.Context, args ...any) (Result, error)

ExecContext выполняет подготовленное утверждение с заданными аргументами и возвращает Result, обобщающий эффект утверждения.

функция (*Stmt) Query

func (s *Stmt) Query(args ...any) (*Rows, error)

Query выполняет подготовленное утверждение запроса с заданными аргументами и возвращает результаты запроса как *Rows.

Query использует context.Background внутри; для указания контекста используйте Stmt.QueryContext.

функция (*Stmt) QueryContext 1.8

func (s *Stmt) QueryContext(ctx context.Context, args ...any) (*Rows, error)

QueryContext выполняет подготовленное утверждение запроса с заданными аргументами и возвращает результаты запроса как *Rows.

функция (*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)
}

тип 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 создаёт подготовленное утверждение для использования внутри транзакции.

Возвращаемое утверждение работает внутри транзакции и будет закрыто, когда транзакция будет подтверждена или отменена.

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

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 всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода 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 всегда возвращает ненулевое значение. Ошибки откладываются до вызова метода 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)

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

Возвращаемое утверждение работает внутри транзакции и будет закрыто, когда транзакция будет подтверждена или отменена.

тип 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