必须使用db门面执行原生sql:一、db::select()执行select并返回stdclass数组;二、db::insert()插入数据但不返回id;三、db::update()更新并返回影响行数;四、db::delete()删除并返回删除行数。

如果您在Laravel项目中需要绕过Eloquent或查询构建器,直接与数据库交互以获得更高控制力或兼容复杂逻辑,则必须使用DB门面提供的原生SQL执行能力。以下是实现该目标的多种方法:
一、使用DB::select()执行SELECT查询
该方法专用于执行只读的SELECT语句,返回结果集数组,每个元素为StdClass对象,适用于获取数据列表或单条记录。它强制要求参数化绑定以防范SQL注入,且仅支持问号占位符或命名绑定(需显式传入PDO选项)。
1、在控制器或服务类中引入DB门面:use Illuminate\Support\Facades\DB;
2、调用DB::select()并传入SQL字符串及参数数组:DB::select("SELECT * FROM users WHERE status = ? AND created_at > ?", [1, '2025-01-01']);
3、若需命名绑定,须手动指定PDO选项:DB::select("SELECT * FROM users WHERE name = :name", ['name' => 'John'], ['PDO::ATTR_EMULATE_PREPARES' => true]);
二、使用DB::insert()执行INSERT语句
该方法用于插入单条或批量记录,底层调用PDO预处理语句,返回布尔值表示是否成功。不返回自增ID,如需获取,应改用DB::table()->insertGetId()或原生statement配合lastInsertId()。
1、插入单条记录:DB::insert("INSERT INTO logs (level, message) VALUES (?, ?)", ['error', 'Something went wrong']);
2、插入多条记录需循环调用或改用批量插入语法(非DB::insert原生支持,需拼接SQL并用DB::statement)。
3、注意:DB::insert()不支持命名绑定,仅接受问号占位符与顺序参数数组。
三、使用DB::update()执行UPDATE语句
该方法执行更新操作并返回受影响行数,便于验证是否匹配到目标记录。它自动处理参数绑定,确保WHERE条件安全,避免全表误更新。
1、基础更新示例:DB::update("UPDATE users SET last_login = ? WHERE id = ?", [now(), 123]);
2、带多个条件的更新:DB::update("UPDATE products SET price = ?, stock = ? WHERE category_id = ? AND active = ?", [99.99, 10, 5, 1]);
3、严禁拼接变量进SQL字符串,例如"WHERE id = " . $id会导致SQL注入风险。
四、使用DB::delete()执行DELETE语句
该方法执行删除操作并返回被删除行数,可用于确认删除范围。其参数绑定机制与DB::update()一致,保障WHERE子句安全性。
1、按主键删除单条:DB::delete("DELETE FROM sessions WHERE id = ?", [$sessionId]);
2、按时间范围清理旧数据:DB::delete("DELETE FROM logs WHERE created_at
3、禁止使用无WHERE子句的DELETE,如"DELETE FROM logs"——必须显式约束删除条件。
五、使用DB::statement()执行通用SQL语句
该方法适用于所有不返回结果集的SQL命令,包括CREATE、DROP、ALTER、TRUNCATE、CALL存储过程、SET变量等。它不进行参数绑定解析,需开发者自行确保SQL结构安全。
1、执行建表语句:DB::statement("CREATE TABLE IF NOT EXISTS backups (id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT)");
2、调用存储过程(假设已存在):DB::statement("CALL generate_monthly_report(?)", ['2026-03']);
3、执行带输出参数的语句时,需依赖底层PDO驱动能力,Laravel不封装此行为,须直接操作PDO实例。











