cpp

MySQL. Добавление записей

Добавить записи в таблицу можно несколькими способами. Начнем с уже знакомого нам метода Exec(). Добавим пользователя в таблицу user:

_, err = db.Exec("INSERT INTO `user` (`email`, `passw`)" +
                 " VALUES ('user1@mail.ru', 'password')")
if err != nil {
   fmt.Fprintln(os.Stderr, err)
   return
}
fmt.Println("Запись добавлена")

Если нам необходимо узнать, какой индекс был автоматически сгенерирован при добавлении записи (поле id_user в таблице user обозначено как auto_increment), то можно воспользоваться объектом sql.Result, возвращаемым через первое значение метода Exec(). Интерфейс sql.Result содержит два метода:

  • LastInsertId() — позволяет получить автоматически сгенерированный индекс при добавлении записи. Формат метода:
(sql.Result).LastInsertId() (int64, error)
  • RowsAffected() — позволяет получить количество строк, затронутых при вставке, обновлении или удалении записей. Формат метода:
(sql.Result).RowsAffected() (int64, error)

Давайте добавим еще одного пользователя и получим сгенерированный индекс (листинг 16.2).

Листинг 16.2. Определение сгенерированного индекса

package main

import (
   "database/sql"
   "fmt"
   "os"

   _ "github.com/go-sql-driver/mysql"
)

func main() {
   db, err := sql.Open("mysql", "root:@/godb")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   defer db.Close()
   result, err := db.Exec("INSERT INTO `user` (`email`, `passw`)" +
                          " VALUES ('user2@mail.ru', 'пароль')")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   index, err := result.LastInsertId()
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   rows, err := result.RowsAffected()
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   fmt.Println("Индекс новой записи:", index)   // 2
   fmt.Println("Число затронутых строк:", rows) // 1
}

В некоторых случаях в SQL-запрос необходимо подставлять данные, полученные от пользователя. Если эти данные не обработать и подставить в SQL-запрос, то пользователь получает возможность видоизменить запрос и, например, зайти в закрытый раздел без ввода пароля. Чтобы значения были правильно подставлены, необходимо внутри SQL-запроса вместо значений указать символы вопросов:

"INSERT INTO `rubr` VALUES (?, ?)"

Подставляемые значения передаются во втором и последующих параметрах метода Exec(). Давайте добавим несколько рубрик в таблицу rubr:

arr := []string{"Программирование", "Музыка",
                "Поисковые ' \" порталы", "Кино"}
for _, v := range arr {
   _, err := db.Exec("INSERT INTO `rubr` (`name_rubr`) VALUES (?)", v)
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
}
fmt.Println("Записи добавлены")

Для правильной подстановки значений можно также использовать подготовленные запросы. Для создания подготовленного запроса предназначен метод Prepare(). Формат метода:

(*sql.DB).Prepare(query string) (*sql.Stmt, error)

Внутри SQL-запроса вместо значений необходимо указать символы вопросов:

"INSERT INTO `rubr` VALUES (?, ?)"

Подставить значения и выполнить запрос можно с помощью метода Exec() структуры sql.Stmt. Формат метода:

(*sql.Stmt).Exec(args ...interface{}) (sql.Result, error)

Когда подготовленный запрос больше не нужен, следует вызвать метод Close(). Формат метода:

(*sql.Stmt).Close() error

Добавим два сайта в таблицу site (листинг 16.3).

Листинг 16.3. Подготовленные запросы

package main

import (
   "database/sql"
   "fmt"
   "os"

   _ "github.com/go-sql-driver/mysql"
)

func main() {
   db, err := sql.Open("mysql", "root:@/godb")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   defer db.Close()
   stmt, err := db.Prepare(
      "INSERT INTO `site` (`id_user`, `id_rubr`, `url`," +
      " `title`, `msg`, `iq`) VALUES (?, ?, ?, ?, ?, ?)")
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   defer stmt.Close()
   _, err = stmt.Exec(1, 1, "https://python.org", "Python",
                      "Язык программирования Python", 50)
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   _, err = stmt.Exec(1, 3, "https://google.ru", "Гугль",
                      "Поисковый портал", 80)
   if err != nil {
      fmt.Fprintln(os.Stderr, err)
      return
   }
   fmt.Println("Записи добавлены")
}

Учебник Go (Golang)
Учебник Go (Golang) в формате PDF

Помощь сайту

ЮMoney (Yandex-деньги): 410011140483022

ПАО Сбербанк:
Счет: 40817810855006152256
Реквизиты банка:
Наименование: СЕВЕРО-ЗАПАДНЫЙ БАНК ПАО СБЕРБАНК
Корреспондентский счет: 30101810500000000653
БИК: 044030653
КПП: 784243001
ОКПО: 09171401
ОКОНХ: 96130
Скриншот реквизитов

cpp