Ответ
Да, умею и регулярно пишу raw SQL-запросы, когда того требует задача. В PHP для этого использую в основном PDO как наиболее универсальный и безопасный способ.
Когда raw SQL необходим или предпочтителен:
- Сложные аналитические запросы:
WITH(CTE), оконные функции, сложныеJOINи агрегации, которые ORM (например, Eloquent) может выразить неэффективно или вообще не может.// Пример: Ранжирование заказов по сумме для каждого клиента $sql = " SELECT customer_id, order_id, total_amount, RANK() OVER (PARTITION BY customer_id ORDER BY total_amount DESC) as rank_in_customer FROM orders WHERE status = 'completed' "; $stmt = $pdo->query($sql); $report = $stmt->fetchAll(PDO::FETCH_ASSOC); - Миграции и работы со схемой БД: Создание индексов, изменение типов колонок, оптимизационные правки.
// В миграции Laravel DB::statement('CREATE INDEX idx_user_email_active ON users (email) WHERE deleted_at IS NULL'); - Массовые операции (Bulk operations):
INSERT ... ON DUPLICATE KEY UPDATEилиCOPYв PostgreSQL для загрузки больших объемов данных, что значительно быстрее постраничного сохранения через ORM.
Безопасный подход с PDO (обязательный):
// 1. Подготовленный запрос с именованными плейсхолдерами - защита от SQL-инъекций
$sql = "
UPDATE products
SET price = :price, updated_at = NOW()
WHERE category_id = :category_id AND stock > 0
";
$stmt = $pdo->prepare($sql);
// 2. Явная привязка значений с указанием типа
$stmt->bindValue(':price', 99.99, PDO::PARAM_STR);
$stmt->bindValue(':category_id', 5, PDO::PARAM_INT);
// 3. Выполнение
$stmt->execute();
// 4. Обработка ошибок
if (!$stmt) {
$errorInfo = $pdo->errorInfo();
throw new RuntimeException("SQL Error: {$errorInfo[2]}");
}
Когда НЕ стоит писать raw SQL:
- Для простых CRUD-операций (создание, чтение одной сущности) — ORM читабельнее и быстрее в разработке.
- Если запрос можно выразить через Query Builder (например, Laravel's
DB::table()) — он часто безопаснее и поддерживает разную СУБД.
Мое правило: Использую ORM для рутинных операций с данными, но без колебаний перехожу на тщательно написанный и протестированный raw SQL для сложной логики выборки, отчетности или оптимизации производительности.
Ответ 18+ 🔞
О, смотри-ка, какой серьёзный вопрос подъехал. Ну что ж, давай разложим по полочкам, как есть, без этих ваших ORM-прослоек, которые иногда только мозги выносят.
Да, конечно, умею и пишу на чистом SQL, когда ситуация того требует. В PHP мой верный друг в этом деле — PDO. Безопасно, универсально, и не надо изобретать велосипед, ёпта.
Вот тебе ситуации, когда голый SQL — это единственный правильный путь, иначе просто пиздец:
- Сложные отчёты и аналитика: Когда нужно ворочать
WITH(эти самые CTE), оконные функции, дикие цепочкиJOIN— тут ORM типа Eloquent просто сдаётся и начинает генерировать такой монструозный запрос, что глянешь на него и сам от себя охуеешь. Проще написать руками.// Допустим, нужно проранжировать заказы по сумме для каждого клиента $sql = " SELECT customer_id, order_id, total_amount, RANK() OVER (PARTITION BY customer_id ORDER BY total_amount DESC) as rank_in_customer FROM orders WHERE status = 'completed' "; $stmt = $pdo->query($sql); $report = $stmt->fetchAll(PDO::FETCH_ASSOC); - Работа со структурой базы: Создание хитрых индексов, изменение типов полей, всякие оптимизации. В миграциях Laravel, например,
DB::statement()— твой лучший друг.// В миграции DB::statement('CREATE INDEX idx_user_email_active ON users (email) WHERE deleted_at IS NULL'); - Массовые вставки или обновления: Когда нужно залить или обновить овердохуища записей.
INSERT ... ON DUPLICATE KEY UPDATEили тот жеCOPYв PostgreSQL сделают это в разы быстрее, чем ты будешь в цикле плодить модели и их сохранять. ORM тут просто сдохнет под нагрузкой.
Но, чувак, главное правило — безопасность, ёбаный в рот! Никаких подстав переменных напрямую в строку, иначе будет тебе хиросима и нагасаки в одном флаконе. Только подготовленные выражения:
// 1. Готовим запрос с плейсхолдерами. Это наше всё против SQL-инъекций.
$sql = "
UPDATE products
SET price = :price, updated_at = NOW()
WHERE category_id = :category_id AND stock > 0
";
$stmt = $pdo->prepare($sql);
// 2. Жёстко привязываем значения, указывая тип. Никаких "авось проскочит".
$stmt->bindValue(':price', 99.99, PDO::PARAM_STR);
$stmt->bindValue(':category_id', 5, PDO::PARAM_INT);
// 3. Поехали.
$stmt->execute();
// 4. Всегда смотрим, что пошло не так, если что.
if (!$stmt) {
$errorInfo = $pdo->errorInfo();
throw new RuntimeException("SQL Error: {$errorInfo[2]}"); // Лучше своё исключение, конечно
}
А когда НЕ надо лезть с raw SQL?
- Для элементарных действий: достать запись по ID, сохранить, удалить. ORM сделает это в одну строчку, и не надо городить.
- Если задачу можно решить через Query Builder (тот же
DB::table()в Laravel). Он часто и безопаснее, и абстрагирует тебя от особенностей конкретной СУБД. Зачем напрягать мозг, если можно не напрягать?
Итог моей философии простой, как три копейки: Для рутины — ORM, для скорости разработки. Для сложной логики, отчётов или когда производительность падает ниже плинтуса — сажусь и пишу чистый, отлаженный SQL. Главное — не превращаться в того распиздая, который всё подряд пишет голыми запросами, а потом неделю ищет, почему всё сломалось после обновления. Чувствуешь грань?