Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当PDO::ATTR_EMULATE_PREPARE=false时,PHP PDO失败_Php_Mysql_Pdo_Prepared Statement_Setattribute - Fatal编程技术网

当PDO::ATTR_EMULATE_PREPARE=false时,PHP PDO失败

当PDO::ATTR_EMULATE_PREPARE=false时,PHP PDO失败,php,mysql,pdo,prepared-statement,setattribute,Php,Mysql,Pdo,Prepared Statement,Setattribute,我有一个应用程序,其中我将一个类作为参数传递给MySQL 8,该类通过使用PDO连接实例与数据库交互 为了创建到数据库的PDO连接,我必须为PDO连接使用设置为false的选项。使用PDO连接的类在执行SELECT或INSERT语句时没有问题,但在以下语句的情况下: 使用数据库名称 创建触发器 下拉触发器 我收到一个错误: SQLSTATE[HY000]:一般错误:2014无法在 其他未缓冲查询处于活动状态。考虑使用 PDO语句::fetchAll()。或者,如果您的代码只是 要在mysql上运

我有一个应用程序,其中我将一个类作为参数传递给MySQL 8,该类通过使用PDO连接实例与数据库交互

为了创建到数据库的PDO连接,我必须为PDO连接使用设置为false的选项。使用PDO连接的类在执行SELECT或INSERT语句时没有问题,但在以下语句的情况下:

使用数据库名称
创建触发器
下拉触发器

我收到一个错误:

SQLSTATE[HY000]:一般错误:2014无法在 其他未缓冲查询处于活动状态。考虑使用 PDO语句::fetchAll()。或者,如果您的代码只是 要在mysql上运行,可以通过设置 PDO::MYSQL\u ATTR\u USE\u BUFFERED\u查询属性

但声明如下:

创建数据库
创建表格

干得好

下面是复制此问题的示例代码:

<?php

header("Content-Type: text/plain");

$user = '';
$pass = '';
$host = '';
$dbname = 'pdo_snippet';

/**
 * Use at first run, the script fails at USE database-name statement
 * but creates database schema $dbName
 */
$dsn = 'mysql:host=' . $host;

/**
 * Use at second run, baypasses fail at USE database-name statement
 * but fails at DROP TRIGGER IF EXISTS;
 */
// $dsn = 'mysql:dbname=' .$dbname. ';host=' . $host;

$options = [];
$options[\PDO::ATTR_ERRMODE] = \PDO::ERRMODE_EXCEPTION;
$options[\PDO::ATTR_EMULATE_PREPARES] = false; # with true no problem

//---------- CONNECT TO DATABASE SERVER ---------
echo "Connect to database";
try {
    $pdo = new \PDO($dsn, $user, $pass, $options);
    
} catch (\Exception $e) {
    $msg = 'PDO could not establish connection to dsn: ' . $dsn;
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//----------------------------------------------

//--------- CREATE SCHEMA IF NOT EXISTS --------
$sqlQuery = 'CREATE DATABASE IF NOT EXISTS `' . $dbname . '`;';
echo "Create database $dbname IF NOT EXISTS";
try {
    $stmt = $pdo->query($sqlQuery);

} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------

//----------- SELECT DEFAULT DATABASE ------------
echo "SELECT FROM default database";
$sqlQuery = "SELECT DATABASE();";
try {
    $stmt = $pdo->query($sqlQuery);

} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------
$defaultDbName = $stmt->fetchColumn();
//------------------------------------------------

//----------- USE datatabase as default ----------
if (empty($defaultDbName)) {
    echo "USE $dbname";
    $sqlQuery = 'USE `' . $dbname . '`;';
    try {
        $stmt = $pdo->query($sqlQuery);
        
    } catch (\Exception $e) {
        $msg = 'Could not execute query: "' . $sqlQuery . '"';
        $msg .= '. PDO exception Msg: ' . $e->getMessage();
        throw new \RuntimeException($msg);
    }
    echo ", DONE.\n";
}
//------------------------------------------------

//------------ CREATE TABLE ----------------------
echo "CREATE TABLE example IF NOT EXISTS";
$sqlQuery = 'CREATE TABLE IF NOT EXISTS `example` (`id` INT AUTO_INCREMENT, `name` VARCHAR(255), PRIMARY KEY(`id`)) ENGINE=InnoDb;';
try {
    $stmt = $pdo->query($sqlQuery);
    
} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------

//------------ DROP TRIGGER IF EXISTS ------------
echo "DROP TRIGGER IF EXISTS";
$sqlQuery = 'DROP TRIGGER IF EXISTS `tr_example_bi_fill`;';
try {
    $stmt = $pdo->query($sqlQuery);
    
} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------

//--------------- CREATE TRIGGER ---------------------
echo "CREATE TRIGGER";
$sqlQuery = "
    CREATE TRIGGER 
        `tr_example_bi_fill`
    BEFORE INSERT ON 
        `example`
    FOR EACH ROW BEGIN
        SET new.`name` = CONCAT(new.`name`, '_TRIGGER');
    END
    ;
";
echo ", DONE.\n";

try {
    $stmt = $pdo->query($sqlQuery);

} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
//------------------------------------------------

//--------------- INSERT INTO --------------------
$value = rand(0,9999);
echo "INSERT INTO TABLE example VALUE '$value'";
$sqlQuery = "INSERT INTO `example` (`name`) VALUES ('$value')";
try {
    $stmt = $pdo->query($sqlQuery);

} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------

// --------------- SELECT FROM -------------------
echo "SELECT FROM example";
$sqlQuery = "SELECT `name` FROM `example` ORDER BY `id` DESC LIMIT 1;";
try {
    $stmt = $pdo->query($sqlQuery);

} catch (\Exception $e) {
    $msg = 'Could not execute query: "' . $sqlQuery . '"';
    $msg .= '. PDO exception Msg: ' . $e->getMessage();
    throw new \RuntimeException($msg);
}
echo ", DONE.\n";
//------------------------------------------------

$result = $stmt->fetchColumn();

echo "Result:\n";
print_r($result);


echo "\n=================\n";
然后我得到:

致命错误:未捕获运行时异常:无法执行查询:“USE
pdo_片段
;”。PDO异常消息:SQLSTATE[HY000]:一般错误: 其他未缓冲查询处于活动状态时,2014无法执行查询。 考虑使用pdoCalp::FutAccess()。或者,如果您的代码 只在mysql上运行,您可以启用查询 通过设置PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY属性进行缓冲

在第二次运行脚本时使用:

$dsn = 'mysql:host=' . $host;
$dsn = 'mysql:dbname=' .$dbname. ';host=' . $host;
首先,USE语句引发的异常会引发另一个异常:

致命错误:未捕获运行时异常:无法执行查询: “如果存在触发器,则丢弃触发器”
tr_示例_bi_fill
”。PDO异常消息: SQLSTATE[HY000]:一般错误:2014无法在 其他未缓冲查询处于活动状态。考虑使用 PDO语句::fetchAll()。或者,如果您的代码只是 要在mysql上运行,可以通过设置 PDO::MYSQL\u ATTR\u USE\u BUFFERED\u查询属性

我想问一下,如何使用PDO连接到数据库的signle实例,并将选项设置为false,并且能够执行
use database name或<代码>下拉触发器
创建触发器

它使我对侧重于
无缓冲查询的错误消息感到困惑

IMO对于缓冲/非缓冲查询和使用
$options[\PDO::MYSQL\u ATTR\u USE\u buffered\u QUERY]=false没有问题
$options[\PDO::MYSQL\u ATTR\u USE\u BUFFERED\u QUERY]=true没有帮助。
也许你能让我明白那个错误

经过一些额外的测试后,我认为问题可能与无缓冲查询有关,因为如果在第二次运行脚本时,我运行脚本时添加了:

$options[\PDO::MYSQL_ATTR_USE_BUFFERED_QUERY] = false;
然后,脚本在以下时间更早地失败:

致命错误:未捕获运行时异常:无法执行查询: 如果不存在,则创建表
示例
id
INT AUTO\u INCREMENT,
name
VARCHAR(255),主键(
id
)引擎=InnoDb;”。PDO异常消息: SQLSTATE[HY000]:一般错误:2014无法在 其他未缓冲查询处于活动状态。考虑使用 PDO语句::fetchAll()。或者,如果您的代码只是 要在mysql上运行,可以通过设置 PDO::MYSQL\u ATTR\u USE\u BUFFERED\u查询属性

使用
下拉触发器(如果存在)未到达有问题的行

因此,看起来至少对于CREATE TABLE这样的语句,解决方案可以是使用
$options[\PDO::MYSQL\u ATTR\u use\u BUFFERED\u QUERY]=true
,我相信这在默认情况下是正确的。但是,
USE…
CREATE TRIGGER…
DROP TRIGGER…
的问题仍然存在

我正在使用: PHP 7.3.8(cli)(构建时间:2019年8月2日05:16:32)(新南威尔士州) 与MySQL相关的扩展:PDO 7.3.8、mysqli 7.3.8、mysqlnd 5.0.12-dev、PDO_mysq 7.3.8

MySQL 8.0.19

两者都基于Docker的官方图片。

您的代码是错误的


这个问题没有足够的信息。您能从这段代码中删除每一条try-catch语句,再次运行它并提供您得到的确切输出吗?另外,PHP版本以及phpinfo()outputFWIW中是否提到“mysqlnd”我在尝试使用simulate_prepares set为false时遇到了很多问题,并且总是让PDO通过将其设置为true来处理事情。也就是说,您使用的是什么版本的PHP和MySQL,以及使用的是什么版本的mysqlnd?@YourCommonSense我编辑了这个问题,因此更明显的是引发了什么异常,以及何时在最后添加了PHP版本及其扩展。@Dave在最后编辑了这个问题。不幸的是,我可能用echo语句误导了您这是错误的(我更改了它)实际查询:$sqlQuery='DROP TRIGGER IF EXISTS
tr_example\u bi_fill
;当PDO::ATTR_EMULATE_PREPARES设置为true时,它是正确的,并且运行良好<代码>使用…
语句也可以正常工作,但当PDO::ATTR\u SIMULATE\u PREADES设置为false时,这两个语句都会失败。为什么必须为false?这似乎是一个bug,它存在了很长一段时间,还没有修复。如果php的新prelereas已经修复,那么您应该尝试使用它。jetSetting PDO::ATTR_EMULATE_PREPARES to FALSE允许在插入中使用。这在一次插入大量错误时速度更快。只需关闭第一个连接并打开第二个连接即可。如果必须在两者之间切换,请将两者都打开
DROP TRIGGER IF EXISTS tr_example_bi_fill