← Назад к вопросам

Как вставить элемент в БД?

1.0 Junior🔥 211 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Вставка элемента в БД: полный подход

Это фундаментальная операция, которая кажется простой, но имеет множество нюансов в production окружении.

1. Базовый SQL подход

const { Pool } = require("pg");

const pool = new Pool();

async function insertUser(name, email) {
  const query = "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id";
  const result = await pool.query(query, [name, email]);
  return result.rows[0];
}

Важно: используем параметризованные запросы ($1, $2) — защита от SQL injection.

2. С использованием ORM (TypeORM/Prisma)

// Prisma
const user = await prisma.user.create({
  data: {
    name: "John",
    email: "john@example.com"
  }
});

// TypeORM
const userRepository = dataSource.getRepository(User);
const user = userRepository.create({
  name: "John",
  email: "john@example.com"
});
await userRepository.save(user);

3. С валидацией и обработкой ошибок

async function createUser(userData) {
  // Валидация
  if (!userData.email || !userData.name) {
    throw new ValidationError("Email и name обязательны");
  }

  try {
    // Проверка уникальности
    const existing = await pool.query(
      "SELECT id FROM users WHERE email = $1",
      [userData.email]
    );
    
    if (existing.rows.length > 0) {
      throw new ConflictError("Email уже существует");
    }

    // Вставка
    const result = await pool.query(
      "INSERT INTO users (name, email, created_at) VALUES ($1, $2, $3) RETURNING id, created_at",
      [userData.name, userData.email, new Date()]
    );

    return result.rows[0];
  } catch (error) {
    if (error.code === "23505") { // Unique constraint violation
      throw new ConflictError("Email уже существует");
    }
    throw error;
  }
}

4. С транзакциями (важно для data integrity)

async function createUserWithProfile(userData, profileData) {
  const client = await pool.connect();
  
  try {
    await client.query("BEGIN");
    
    // Вставляем пользователя
    const userResult = await client.query(
      "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id",
      [userData.name, userData.email]
    );
    const userId = userResult.rows[0].id;
    
    // Вставляем профиль
    await client.query(
      "INSERT INTO profiles (user_id, bio, avatar) VALUES ($1, $2, $3)",
      [userId, profileData.bio, profileData.avatar]
    );
    
    await client.query("COMMIT");
    return userId;
  } catch (error) {
    await client.query("ROLLBACK");
    throw error;
  } finally {
    client.release();
  }
}

5. Batch вставка (для производительности)

async function insertManyUsers(users) {
  // Построение запроса
  const values = users
    .map((_, i) => `($${i * 2 + 1}, $${i * 2 + 2})`)
    .join(",");
  
  const params = users.flatMap(u => [u.name, u.email]);
  
  const query = `INSERT INTO users (name, email) VALUES ${values} RETURNING id`;
  return await pool.query(query, params);
}

6. Best Practices в production:

  • Всегда валидируй данные перед вставкой
  • Используй параметризованные запросы (защита от SQL injection)
  • Проверяй уникальные ограничения перед вставкой или обрабатывай constraint errors
  • Используй транзакции для связанных операций
  • Логируй ошибки для отладки
  • Используй indexes на часто запрашиваемых полях
  • Кешируй результаты если нужно читать их часто

7. Обработка ошибок

const ErrorCodes = {
  UNIQUE_VIOLATION: "23505",
  NOT_NULL_VIOLATION: "23502",
  FOREIGN_KEY_VIOLATION: "23503"
};

try {
  await insertUser(name, email);
} catch (error) {
  switch (error.code) {
    case ErrorCodes.UNIQUE_VIOLATION:
      return res.status(409).json({ error: "Email уже существует" });
    case ErrorCodes.NOT_NULL_VIOLATION:
      return res.status(400).json({ error: "Обязательное поле не заполнено" });
    default:
      return res.status(500).json({ error: "Внутренняя ошибка" });
  }
}

Ключь к успеху — думать не только о happy path, но и о всех edge cases: дублирование данных, нарушение ограничений, network timeouts, connection pool exhaustion.

Как вставить элемент в БД? | PrepBro