> Как вернуть только что вставленную строку в базе данных (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Ozon

Стек: Go

> Пример ответа

В Go для возврата только что вставленной строки чаще всего используется конструкция RETURNING в SQL-запросе. Это позволяет получить данные сразу после вставки, без дополнительного SELECT.

Пример с использованием database/sql и PostgreSQL:

GO
type User struct {
ID int
Name string
CreatedAt time.Time
}
func InsertUser(db *sql.DB, name string) (*User, error) {
query := `INSERT INTO users (name) VALUES ($1) RETURNING id, name, created_at`
user := &User{}
err := db.QueryRow(query, name).Scan(&user.ID, &user.Name, &user.CreatedAt)
if err != nil {
return nil, fmt.Errorf("insert user: %w", err)
}
return user, nil
}

Если база данных не поддерживает RETURNING (например, MySQL), можно использовать LastInsertId() для автоинкрементных ключей, а затем выполнить SELECT:

GO
func InsertUserMySQL(db *sql.DB, name string) (*User, error) {
result, err := db.Exec(`INSERT INTO users (name) VALUES (?)`, name)
if err != nil {
return nil, err
}
id, err := result.LastInsertId()
if err != nil {
return nil, err
}
user := &User{}
err = db.QueryRow(`SELECT id, name, created_at FROM users WHERE id = ?`, id).
Scan(&user.ID, &user.Name, &user.CreatedAt)
return user, err
}

Для пакетной вставки используйте RETURNING с итерацией по строкам через Rows:

GO
func InsertUsers(db *sql.DB, names []string) ([]User, error) {
query := `INSERT INTO users (name) VALUES ($1) RETURNING id, name, created_at`
var users []User
for _, name := range names {
user := User{}
err := db.QueryRow(query, name).Scan(&user.ID, &user.Name, &user.CreatedAt)
if err != nil {
return nil, err
}
users = append(users, user)
}
return users, nil
}

Важно: используйте подготовленные запросы для защиты от SQL-инъекций, как показано в примерах.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью