Использование подготовленных операторов

Вы можете определить подготовленный оператор для повторного использования. Это может помочь вашему коду работать немного быстрее, избегая накладных расходов на повторное создание оператора каждый раз, когда ваш код выполняет операцию с базой данных.

Примечание: Заполнители параметров в подготовленных операторах зависят от используемой СУБД и драйвера. Например, драйвер pq для Postgres требует заполнитель вида $1 вместо ?.

Что такое подготовленный оператор?

Подготовленный оператор — это SQL-запрос, который анализируется и сохраняется СУБД, как правило, содержащий заполнители, но без фактических значений параметров. Позднее такой оператор может быть выполнен с набором значений параметров.

Как использовать подготовленные операторы

Когда вы ожидаете выполнять один и тот же SQL-запрос неоднократно, вы можете использовать sql.Stmt для подготовки SQL-оператора заранее, а затем выполнять его по мере необходимости.

В следующем примере создаётся подготовленный оператор, который выбирает конкретный альбом из базы данных. DB.Prepare возвращает sql.Stmt, представляющий подготовленный оператор для заданного текста SQL. Вы можете передать параметры SQL-оператора в Stmt.Exec, Stmt.QueryRow или Stmt.Query, чтобы выполнить оператор.

<code>// AlbumByID retrieves the specified album.
func AlbumByID(id int) (Album, error) {
  // Define a prepared statement. You'd typically define the statement
  // elsewhere and save it for use in functions such as this one.
  stmt, err := db.Prepare("SELECT * FROM album WHERE id = ?")
  if err != nil {
    log.Fatal(err)
  }
  defer stmt.Close()

  var album Album

  // Execute the prepared statement, passing in an id value for the
  // parameter whose placeholder is ?
  err := stmt.QueryRow(id).Scan(&album.ID, &album.Title, &album.Artist, &album.Price, &album.Quantity)
  if err != nil {
    if err == sql.ErrNoRows {
      // Handle the case of no rows returned.
    }
    return album, err
  }
  return album, nil
}
</code>

Поведение подготовленного оператора

Подготовленный sql.Stmt

Предоставляет обычные методы Exec, QueryRow и Query для вызова инструкции. Более подробно о том, как использовать эти методы, можно узнать в разделах Запросы к данным и Выполнение SQL-инструкций, не возвращающих данные.

Однако, поскольку sql.Stmt уже представляет собой предварительно подготовленную SQL-инструкцию, его методы Exec, QueryRow и Query принимают только значения параметров SQL, соответствующие заполнителям, исключая текст SQL.

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

  • DB.Prepare и DB.PrepareContext создают подготовленную инструкцию, которую можно выполнить изолированно, вне транзакции, подобно тому, как это делают DB.Exec и DB.Query.
  • Tx.Prepare, Tx.PrepareContext, Tx.Stmt и Tx.StmtContext создают подготовленную инструкцию для использования в конкретной транзакции. Prepare и PrepareContext используют текст SQL для определения инструкции. Stmt и StmtContext используют результат вызова DB.Prepare или DB.PrepareContext. То есть, они преобразуют инструкцию, не предназначенную для транзакций, в инструкцию, подходящую для данной транзакции.
  • Conn.PrepareContext создаёт подготовленную инструкцию из sql.Conn, который представляет зарезервированное подключение.

Убедитесь, что метод stmt.Close вызывается, когда код больше не нуждается в инструкции. Это освободит все ресурсы базы данных (например, базовые подключения), связанные с ней. Для инструкций, являющихся локальными переменными внутри функции, достаточно добавить defer stmt.Close().

Функции для создания подготовленной инструкции

Функция Описание
DB.Prepare
DB.PrepareContext
Подготавливает инструкцию для выполнения в изоляции или которая будет преобразована в инструкцию внутри транзакции с использованием Tx.Stmt.
Tx.Prepare
Tx.PrepareContext
Tx.Stmt
Tx.StmtContext
Подготавливает инструкцию для использования в конкретной транзакции. Более подробно см. Выполнение транзакций.
Conn.PrepareContext Используется с зарезервированными соединениями. Более подробно см. Управление соединениями.
GoRu.dev Golang на русском

На сайте представлена адаптированная под русский язык документация языка программирования Golang