0Pricing
Go Academy · Урок

Запрос строк

Читайте наборы результатов

«Запрос строк» — бесплатный урок Go Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Получение наборов результатов

Используйте Query для операторов, возвращающих строки, например SELECT. Он возвращает объект *sql.Rows, по которому выполняется итерация. Для одного значения проще использовать QueryRow.

db.Query

Query отправляет SQL-запрос и возвращает строки вместе с ошибкой. Всегда проверяйте ошибку перед использованием строк.

rows, err := db.Query("SELECT id, name FROM users WHERE active = $1", true)
if err != nil {
    log.Fatal(err)
}

Всегда используйте defer rows.Close()

Строки удерживают соединение с базой данных, пока не будут закрыты. defer rows.Close() возвращает соединение в пул. Если забыть об этом, при высокой нагрузке соединения начнут утекать.

defer rows.Close()

Итерация с rows.Next

rows.Next() переходит к следующей строке и возвращает false после завершения. Внутри цикла вызовите Scan, чтобы скопировать значения столбцов в переменные.

for rows.Next() {
    var id int
    var name string
    if err := rows.Scan(&id, &name); err != nil {
        log.Fatal(err)
    }
    fmt.Println(id, name)
}

Scan принимает указатели

Scan записывает данные в переданные переменные, поэтому необходимо передавать указатели (&id, &name). Число и порядок указателей должны соответствовать выбранным столбцам.

Проверка rows.Err

Цикл может завершиться как из-за окончания данных, так и из-за ошибки, возникшей во время итерации. После цикла вызовите rows.Err(), чтобы обнаружить ошибку итерации.

if err := rows.Err(); err != nil {
    log.Fatal(err)
}

QueryRow для одной строки

Если ожидается ровно одна строка, сочетание QueryRow и Scan будет проще. Если подходящей строки нет, Scan возвращает sql.ErrNoRows.

var name string
err := db.QueryRow("SELECT name FROM users WHERE id = $1", 7).Scan(&name)
if err == sql.ErrNoRows {
    fmt.Println("not found")
}

Рабочая имитация Scan

Для настоящих запросов нужна база данных, поэтому этот рабочий пример моделирует последовательность Query, Next, Scan на срезе в памяти и показывает схему итерации.

package main

import "fmt"

type Row struct {
    ID   int
    Name string
}

func main() {
    rows := []Row{{1, "Ada"}, {2, "Lin"}, {3, "Guido"}}
    for i := 0; i < len(rows); i++ {
        var id int
        var name string
        id = rows[i].ID
        name = rows[i].Name
        fmt.Printf("id=%d name=%s\n", id, name)
    }
    fmt.Println("scanned", len(rows), "rows")
}

Обработка NULL

Столбец NULL нельзя просканировать в обычную строку или целое число. Используйте sql.NullString, sql.NullInt64 или тип-указатель, чтобы код мог отличать NULL от пустого значения.

var email sql.NullString
rows.Scan(&email)
if email.Valid {
    fmt.Println(email.String)
}

Сканирование в структуры

Стандартная библиотека сканирует данные в отдельные переменные, а не в структуры целиком. Сопоставьте столбцы с полями структуры, передав &u.ID, &u.Name. Библиотеки вроде sqlx автоматизируют этот процесс.

Избегайте SELECT *

Явно перечисляйте столбцы, чтобы порядок Scan оставался неизменным. Изменение схемы с добавлением столбца незаметно сломает позиционный Scan, если вы полагались на SELECT *.

Проверка знаний

Проверьте свои знания о запросах.

Итоги

Вы изучили получение строк:

  • Query возвращает *sql.Rows; используйте defer rows.Close()
  • Перебирайте строки с помощью rows.Next и копируйте значения через Scan в указатели
  • Проверяйте rows.Err() после цикла
  • Используйте QueryRow для одной строки; при отсутствии результата возвращается sql.ErrNoRows
  • Используйте типы Null для допускающих NULL столбцов

Часто задаваемые вопросы

Урок «Запрос строк» бесплатный?

Да — полный текст урока «Запрос строк» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «Запрос строк»?

Читайте наборы результатов Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Запрос строк»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Открытие соединения
  2. Запрос строк
  3. Подготовленные операторы
  4. Транзакции
← Назад к Go Academy