PHP Conference Japan 2024

PDO::exec

(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 0.1.0)

PDO::exec执行 SQL 语句并返回受影响的行数

描述

public PDO::exec(string $statement): int|false

PDO::exec() 在单个函数调用中执行 SQL 语句,并返回该语句影响的行数。

PDO::exec() 不返回 SELECT 语句的结果。对于在程序中只需要执行一次的 SELECT 语句,请考虑使用 PDO::query()。对于需要执行多次的语句,请使用 PDO::prepare() 准备一个 PDOStatement 对象,并使用 PDOStatement::execute() 执行该语句。

参数

statement

要准备和执行的 SQL 语句。

查询中的数据应该 正确转义

返回值

PDO::exec() 返回由您发出的 SQL 语句修改或删除的行数。如果没有影响任何行,PDO::exec() 返回 0

警告

此函数可能会返回布尔值 false,但也可能返回一个非布尔值,该值计算结果为 false。有关更多信息,请阅读有关 布尔值 的部分。使用 === 运算符 测试此函数的返回值。

以下示例错误地依赖于 PDO::exec() 的返回值,其中影响 0 行的语句会导致调用 die()

<?php
$db
->exec() or die(print_r($db->errorInfo(), true)); // 错误
?>

错误/异常

如果属性 PDO::ATTR_ERRMODE 设置为 PDO::ERRMODE_WARNING,则会发出级别为 E_WARNING 的错误。

如果属性 PDO::ATTR_ERRMODE 设置为 PDO::ERRMODE_EXCEPTION,则会抛出一个 PDOException

示例

示例 #1 发出 DELETE 语句

计算没有 WHERE 子句的 DELETE 语句删除的行数。

<?php
$dbh
= new PDO('odbc:sample', 'db2inst1', 'ibmdb2');

/* 从 FRUIT 表中删除所有行 */
$count = $dbh->exec("DELETE FROM fruit");

/* 返回已删除的行数 */
print "已删除 $count 行。\n";
?>

以上示例将输出

Deleted 1 rows.

参见

添加注释

用户贡献的注释 5 条注释

44
david at acz dot org
18 年前
此函数不能与任何返回结果的查询一起使用。这包括 SELECT、OPTIMIZE TABLE 等。
2
Sbastien
2 年前
请注意,使用 MySQL,您可以使用 INSERT 检测到重复键(1 = INSERT,2 = UPDATE)

<?php

// MySQL 特定的 INSERT UPDATE 类语法
$sql = <<<SQL
INSERT INTO customers
SET
id =
{$pdo->quote($id)},
name =
{$pdo->quote($name)},
address =
{$pdo->quote($address)}
AS new
ON DUPLICATE KEY UPDATE
name = new.name,
address = new.address
SQL;

$result = $pdo->exec($sql);

if (
$result === 1) {
// 已执行新的行插入
} elseif ($result === 2) {
// 已执行现有行的更新
}
13
soletan at toxa dot de
18 年前
值得注意的是,除了上面文档中给出的提示外,使用 prepare、bind 和 execute 比多次查询语句提供了更多好处:性能和安全性!

如果您使用 INSERT INTO ... 将一些二进制数据(例如图像文件)插入数据库,那么它可能会提高解析语句的性能,因为它保持较小(只有几个字节,而图像可能是几兆字节),并且不需要转义/引用文件的二进制数据以成为正确的字符串值。

最后,例如,如果您想要获得一个不受 SQL 注入攻击影响的更安全的 PHP 应用程序,则_必须_考虑对包含数据的每个语句(如包含 WHERE 子句的 INSERT 或 SELECT)使用 prepare/execute。使用 prepare、bind 和 execute 将语句代码与相关数据分离是最佳方法 - 快速且安全!您甚至不需要转义/引用/格式检查任何数据。
6
calin at NOSPAM dot softped dot com
9 年前
当使用 PDO_DBLIB 和 FreeTDS 时,PDO::eval() 对于某些语句(例如 CREATE TABLE)可能会返回 `false`,即使操作已成功完成。因此,它不是测试操作状态的可靠方法。

PDO::errorInfo() 可用于测试 SQLSTATE 错误代码是否为 '00000'(成功)和 '01000'(成功并带警告)。

<?php
function execute(PDO $conn, $sql) {
$affected = $conn->exec($sql);
if (
$affected === false) {
$err = $conn->errorInfo();
if (
$err[0] === '00000' || $err[0] === '01000') {
return
true;
}
}
return
$affected;
}
?>

PDO::errorInfo(): https://php.net/manual/en/pdo.errorinfo.php
SQLSTATE 代码列表:http://www-01.ibm.com/support/knowledgecenter/SSGU8G_11.70.0/com.ibm.sqls.doc/ids_sqs_0809.htm
4
roberto at spadim dot com dot br
17 年前
此函数不执行 multi_query
要获取它,请查看 SQLITE_EXEC 注释,那里有一个 pereg 函数可以获取所有查询并依次执行,然后返回最后一个查询的结果。
To Top