SQLite3Stmt::execute

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

SQLite3Stmt::execute执行预备语句并返回结果集对象

描述

public SQLite3Stmt::execute(): SQLite3Result|false

执行预备语句并返回结果集对象。

警告

通过在同一个语句对象上调用此方法检索到的结果集对象不是独立的,而是共享相同的底层结构。因此,建议在同一个语句对象上再次调用 SQLite3Stmt::execute() 之前,调用 SQLite3Result::finalize()

参数

此函数没有参数。

返回值

如果成功执行预备语句,则返回一个 SQLite3Result 对象,如果失败,则返回 false

参见

添加注释

用户贡献的注释 2 个注释

gmail@asmqb7
8 年前
目前,SQLite3 PHP 绑定(不是 SQLite3 本身)存在一个问题,导致所有查询都被执行两次。它显然已经存在一段时间了。

有关更多信息,请参见此处:https://bugs.php.net/bug.php?id=64531

在发现上述问题之前,我发布了以下内容:http://stackoverflow.com/questions/36617708/odd-behavior-with-sqlite3-non-select-prepared-transactions-and-fetcharray(包括复制粘贴的错误演示)

解决方法:我强烈建议将可能在非 SELECT 查询结果上运行 fetchArray() 的任何代码包装在 numColumns() 检查中,如下所示

<?php

$op
= $db->prepare(...);

$r = $op->execute(); // 查询 #1

if ($r->numColumns()) { // 返回列数,这里用作真/假测试
while ($row = $r->fetchArray(SQLITE3_ASSOC)) { // 查询 #2
// 您的代码在此处
}
}

?>

澄清

- 查询 #1 是 SQLite3 查询第一次执行的地方,查询 #2 是查询再次执行的地方。是的,*所有内容* 都被执行了两次;这就是错误。

- 如果您的代码只从数据库中读取而不会更改数据库(例如,不会导致数据库更改触发的 SELECT),那么您就没事。您的查询运行两次,但它不会更改结果。

- 如果您的代码要写入数据库 - 例如 INSERT - 那么如果列数为零,则*必须*不要运行 fetchArray()(并再次执行查询)。

- 它在手册中没有记录,但在这里 -https://php.net/manual/en/book.sqlite3.php#113144 - 用户 'bohwaz' 提到从 PHP 5.3.11 开始,还有一个 SQLite3Stmt::readOnly() 函数可以告诉您是否刚刚写入数据库。这目前没有记录,但可能是 numColumns() 的更合适的替代方案(我不确定它做了什么,它可能与 numColumns() 相同)。

您可能更喜欢使用 PDO 来进行更高容量的 SQLite3 工作。讽刺的是,这个绑定更轻量级,并提供对一些特定于 SQLite3 的原语和行为的直接访问... 但它运行所有查询两次。

[[注意主持人(此部分可以在阅读后删除;我对以下内容也持开放态度)

- 请不要将此评论视为错误报告 - 我只是希望其他人知道这个问题,这样他们就不会花几个小时挠头了。:P

- 截至提交此评论的日期,此页面有一个未经批准的 diff 停留在 DocBook 中,因此我无法添加类似 "由于错误 #64531,建议您将 fetchArray() 包装在 numColumns() 中..." 的内容,我认为这将比此评论更有说服力,直到这个错误得到修复。]]]
macguru
7 年前
通过在执行后对结果进行 finalize(),我成功地避免了预备语句多次执行。

$stmt->execute()->finalize();

希望这能帮助其他人。
To Top