PDO::exec(长文讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观

在 PHP 数据库编程中,PDO::exec 是一个高效且实用的方法,尤其适用于执行不需要返回结果集的 SQL 操作。无论是创建数据库表、批量插入数据,还是更新和删除记录,PDO::exec 都能以简洁的方式完成任务。本文将从基础概念到实战案例,逐步解析 PDO::exec 的核心功能、使用技巧及常见问题,帮助开发者快速掌握这一工具。


一、什么是 PDO 和 PDO::exec?

1.1 PDO 简介

PHP Data Objects(PDO)是 PHP 内置的一个数据库抽象层,支持多种数据库(如 MySQL、PostgreSQL、SQLite 等)。它提供了一套统一的接口,使开发者无需为不同数据库编写重复代码。

1.2 PDO::exec 的定义

PDO::exec 是 PDO 对象的一个方法,用于执行 SQL 语句,主要适用于不返回结果集的操作,例如:

  • INSERT(插入数据)
  • UPDATE(更新数据)
  • DELETE(删除数据)
  • CREATE TABLE(创建表)
  • ALTER TABLE(修改表结构)

PDO::query 不同,PDO::exec 不会返回查询结果,而是返回受影响的行数,或在发生错误时返回 false

1.3 形象比喻

可以将 PDO::exec 想象为一位快递员:

  • 任务明确:你告诉他“把包裹送到某地址”(执行 SQL 指令)。
  • 不带回执:快递员完成任务后,只会告诉你“包裹已送达”(返回受影响行数),而不会带回包裹内容。

二、PDO::exec 的基本语法与参数

2.1 方法语法

mixed PDO::exec ( string $statement )  
  • 参数

    • $statement:要执行的 SQL 语句,必须为字符串类型。
  • 返回值

    • 成功时返回受影响的行数(如插入、更新、删除操作的行数)。
    • 失败时返回 false,并抛出 PDOException 异常(需开启异常模式)。

2.2 使用步骤

  1. 建立数据库连接:使用 PDO 构造函数创建数据库连接对象。
  2. 执行 SQL 语句:通过 PDO::exec 方法传递 SQL 语句。
  3. 处理结果或错误:根据返回值判断操作是否成功。

三、实战案例:从基础到进阶

3.1 案例 1:创建数据库表

需求:创建一个名为 users 的表,包含 idnameemail 字段。

// 1. 连接数据库  
$dsn = 'mysql:host=localhost;dbname=test';  
$username = 'root';  
$password = '';  
$options = [  
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,  
];  

try {  
    $pdo = new PDO($dsn, $username, $password, $options);  
} catch (PDOException $e) {  
    die("连接失败: " . $e->getMessage());  
}  

// 2. 执行 SQL 创建表  
$sql = "CREATE TABLE users (  
    id INT AUTO_INCREMENT PRIMARY KEY,  
    name VARCHAR(50) NOT NULL,  
    email VARCHAR(100) UNIQUE  
)";  

// 3. 使用 exec 执行  
$affectedRows = $pdo->exec($sql);  

if ($affectedRows === false) {  
    echo "创建表失败!";  
} else {  
    echo "表创建成功!";  
}  

3.2 案例 2:批量插入数据

需求:向 users 表中插入 3 条用户数据。

// SQL 语句(注意:INSERT 可以批量操作)  
$insertSql = "INSERT INTO users (name, email) VALUES  
    ('Alice', 'alice@example.com'),  
    ('Bob', 'bob@example.com'),  
    ('Charlie', 'charlie@example.com')";  

// 执行并获取受影响行数  
$affectedRows = $pdo->exec($insertSql);  

echo "成功插入 $affectedRows 条记录。";  

3.3 案例 3:更新与删除操作

需求:将用户 Alice 的邮箱改为 alice_new@example.com,并删除 Charlie 的记录。

// 更新操作  
$updateSql = "UPDATE users SET email = 'alice_new@example.com' WHERE name = 'Alice'";  
$pdo->exec($updateSql);  

// 删除操作  
$deleteSql = "DELETE FROM users WHERE name = 'Charlie'";  
$pdo->exec($deleteSql);  

四、关键知识点详解

4.1 返回值的解读

  • 成功时:返回受影响的行数。例如:
    • 插入 3 条数据 → 返回 3
    • 更新 1 条数据 → 返回 1
  • 失败时:返回 false,常见原因包括:
    • SQL 语法错误。
    • 主键冲突或违反唯一约束(如重复的 email)。

4.2 错误处理与调试

4.2.1 异常模式

通过设置 PDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION,可在错误发生时自动抛出异常:

try {  
    $pdo->exec("INSERT INTO users (name) VALUES ('Dave')"); // 缺少 email 字段,会触发错误  
} catch (PDOException $e) {  
    echo "错误: " . $e->getMessage();  
}  

4.2.2 非异常模式

若未开启异常模式,需手动检查返回值:

$result = $pdo->exec("INSERT INTO users (name) VALUES ('Dave')");  
if ($result === false) {  
    // 获取错误信息  
    $errorInfo = $pdo->errorInfo();  
    echo "错误代码: " . $errorInfo[0];  
    echo "错误描述: " . $errorInfo[2];  
}  

4.3 PDO::exec 与 PDO::query 的区别

特性PDO::execPDO::query
返回值受影响的行数或 false返回 PDOStatement 对象或 false
适用场景不返回结果集的操作(如 DML)返回结果集的操作(如 SELECT)
占位符支持不支持参数绑定支持参数绑定(需配合 prepare

比喻

  • PDO::exec 是“执行官”,专注于完成任务,不关心结果内容。
  • PDO::query 是“调查员”,会带回详细的结果报告。

五、进阶技巧与最佳实践

5.1 批量操作优化

通过将多个 SQL 语句合并为一条,减少网络交互次数,提升性能。例如:

// 原始写法(多次执行)  
$pdo->exec("INSERT INTO users...");  
$pdo->exec("INSERT INTO orders...");  

// 优化后(单次执行)  
$pdo->exec("INSERT INTO users...; INSERT INTO orders...");  

5.2 避免 SQL 注入的注意事项

虽然 PDO::exec 不支持参数绑定(占位符),但在涉及动态数据时,必须使用 PDO::prepare 配合占位符。例如:

// 错误示例(易受 SQL 注入攻击)  
$userInput = "Robert'; DROP TABLE users; --";  
$pdo->exec("INSERT INTO users (name) VALUES ('$userInput')");  

// 正确示例(使用 prepare)  
$stmt = $pdo->prepare("INSERT INTO users (name) VALUES (?)");  
$stmt->execute([$userInput]);  

5.3 事务的结合使用

在需要保证操作原子性时,可结合事务使用 PDO::exec

// 开启事务  
$pdo->beginTransaction();  

try {  
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE user_id = 1");  
    $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE user_id = 2");  
    $pdo->commit(); // 提交事务  
} catch (PDOException $e) {  
    $pdo->rollBack(); // 回滚事务  
    echo "转账失败!";  
}  

六、常见问题解答

Q1:为什么 PDO::exec 返回 false

可能原因包括:

  • SQL 语法错误(如缺少引号、字段名错误)。
  • 数据库权限不足。
  • 违反约束(如唯一索引冲突)。
    解决方法:检查错误信息(通过 errorInfo() 或异常捕获)。

Q2:PDO::exec 能执行 SELECT 语句吗?

不能。SELECT 需使用 PDO::queryPDO::prepare

Q3:如何获取自增 ID(如插入后的 id)?

插入操作后,使用 PDO::lastInsertId() 方法:

$pdo->exec("INSERT INTO users (name) VALUES ('Eve')");  
$newId = $pdo->lastInsertId();  
echo "新插入的 ID 是:$newId";  

结论

PDO::exec 是 PHP 数据库操作中不可或缺的工具,尤其适合执行 DML(数据操作语言)语句。通过本文的案例和解析,开发者可以掌握其核心功能、错误处理技巧,以及与事务、参数化查询的结合应用。无论是基础的增删改操作,还是复杂的批量处理,PDO::exec 都能以简洁的方式提升开发效率。

在实际开发中,建议始终开启异常模式,并结合 PDO::prepare 防范 SQL 注入。随着对 PDO 框架的深入理解,开发者将能更灵活地应对各种数据库操作场景,写出健壮、高效的代码。

最新发布