Запрос строк
Читайте наборы результатов
«Запрос строк» — бесплатный урок 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 — локальная установка не требуется.