php Laravel:一般错误:1615 准备好的语句需要重新准备

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31957441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:44:34  来源:igfitidea点击:

Laravel: General error: 1615 Prepared statement needs to be re-prepared

phpdatabaselaraveleloquentmariadb

提问by Tenaciousd93

I'm using last version of laravel (5.1) in a homestead virtual machine (vagrant).

我在宅基地虚拟机 (vagrant) 中使用最新版本的 laravel (5.1)。

I connect my project to a local mariaDB server, in which I have some table and 2 db-view.

我将我的项目连接到本地 mariaDB 服务器,其中有一些表和 2 个 db-view。

Since I made some select only on the db-view tables, I receive back randomly this error:

由于我只在 db-view 表上做了一些选择,我随机收到这个错误:

General error: 1615 Prepared statement needs to be re-prepared

一般错误:1615 Prepared statement 需要重新准备

From today, I always get this error when made select only on the db views. If I open my phpMyAdmin and make the same select it return the correct result.

从今天开始,仅在 db 视图上进行选择时,我总是会收到此错误。如果我打开我的 phpMyAdmin 并进行相同的选择,它会返回正确的结果。

I tried to open php artisan tinkerand select one record of the db-view but it return the same error:

我试图打开php artisan tinker并选择 db-view 的一条记录,但它返回相同的错误:

// Select one user from user table
>>> $user = new App\User
=> <App\User #000000006dc32a890000000129f667d2> {}
>>> $user = App\User::find(1);
=> <App\User #000000006dc32a9e0000000129f667d2> {
       id: 1,
       name: "Luca",
       email: "[email protected]",
       customerId: 1,
       created_at: "2015-08-06 04:17:57",
       updated_at: "2015-08-11 12:39:01"
   }
>>> 
// Select one source from Source db-view
>>> $source = new App\Source
=> <App\Source #000000006dc32a820000000129f667d2> {}
>>> $source = App\Source::find(1);
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared (SQL: select * from `sources` where `sources`.`id` = 1 limit 1)'

How can I fix that? I read about a problem with mysqldump (but not in my case) and to increase value of table_definition_cachebut it is not sure that it will work and I can't modify them.

我该如何解决?我读到了 mysqldump 的一个问题(但不是在我的情况下)并增加了 的值,table_definition_cache但不确定它是否会起作用,我无法修改它们。

Is this a kind of laravel bug?

这是一种laravel错误吗?

How can I figure that out?

我怎么能弄明白呢?



Edit:

编辑:

As asked, I add my model source code. Source.php:

按照要求,我添加了我的模型源代码。源.php:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Source extends Model
{
    protected $table = 'sources';


    /*
    |--------------------------------------------------------------------------
    | FOREIGN KEYS
    |--------------------------------------------------------------------------
    */

    /**
     * 
     * @return [type] [description]
     */
    public function customersList(){
        return $this->hasMany("App\CustomerSource", "sourceId", "id");
    }


    /**
     * 
     * @return [type] [description]
     */
    public function issues(){
        return $this->hasMany("App\Issue", "sourceId", "id");
    }
}


Edit 2:

编辑2:

If I execute the same query in the project with mysqli it works:

如果我在项目中使用 mysqli 执行相同的查询,它会起作用:

$db = new mysqli(getenv('DB_HOST'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'));
if($db->connect_errno > 0){
    dd('Unable to connect to database [' . $db->connect_error . ']');
}
$sql = "SELECT * FROM `sources` WHERE `id` = 4";
if(!$result = $db->query($sql)){
    dd('There was an error running the query [' . $db->error . ']');
}

dd($result->fetch_assoc());


EDIT 3: Afeter 2 month, I'm still there. Same error and no solution found. I decide to try a little solution in aritsan tinker but no good news. I report what I've tried:

编辑 3:2 个月后,我还在那里。同样的错误,没有找到解决方案。我决定在 aritsan tinker 中尝试一些解决方案,但没有好消息。我报告了我的尝试:

First try to fetch a table model:

首先尝试获取表模型:

>>> $user = \App\User::find(1);
=> App\User {#697
     id: 1,
     name: "Luca",
     email: "[email protected]",
     customerId: 1,
     created_at: "2015-08-06 04:17:57",
     updated_at: "2015-10-27 11:28:14",
   }

Now try to fetch a view table model:

现在尝试获取一个视图表模型:

>>> $ir = \App\ContentRepository::find(15);
Illuminate\Database\QueryException with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dbname.content_repositories' doesn't exist (SQL: select * from `content_repositories` where `content_repositories`.`id` = 1 limit 1)'

When contentRepository doesn't have correct table name setup inside the model ContentRepository.php:

当 contentRepository 在模型 ContentRepository.php 中没有正确的表名设置时:

>>> $pdo = DB::connection()->getPdo();
=> PDO {#690
     inTransaction: false,
     errorInfo: [
       "00000",
       1146,
       "Table 'dbname.content_repositories' doesn't exist",
     ],
     attributes: [
       "CASE" => NATURAL,
       "ERRMODE" => EXCEPTION,
       "AUTOCOMMIT" => 1,
       "PERSISTENT" => false,
       "DRIVER_NAME" => "mysql",
       "SERVER_INFO" => "Uptime: 2513397  Threads: 12  Questions: 85115742  Slow queries: 6893568  Opens: 1596  Flush tables: 1  Open tables: 936  Queries per second avg: 33.864",
       "ORACLE_NULLS" => NATURAL,
       "CLIENT_VERSION" => "mysqlnd 5.0.11-dev - 20120503 - $Id: id_here $",
       "SERVER_VERSION" => "5.5.5-10.0.17-MariaDB-1~wheezy-wsrep-log",
       "STATEMENT_CLASS" => [
         "PDOStatement",
       ],
       "EMULATE_PREPARES" => 0,
       "CONNECTION_STATUS" => "localiphere via TCP/IP",
       "DEFAULT_FETCH_MODE" => BOTH,
     ],
   }
>>> 

CHANGE TABLE VALUE INSIDE model ContentRepository.php:

在模型 ContentRepository.php 中更改表值:

>>> $ir = \App\ContentRepository::find(15);
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared (SQL: select * from `contentRepository` where `contentRepository`.`id` = 15 limit 1)'

When it is correct, pay attention to "errorInfo" that is missing:

当它正确时,注意缺少的“errorInfo”

>>> $pdo = DB::connection()->getPdo();
=> PDO {#690
     inTransaction: false,
     attributes: [
       "CASE" => NATURAL,
       "ERRMODE" => EXCEPTION,
       "AUTOCOMMIT" => 1,
       "PERSISTENT" => false,
       "DRIVER_NAME" => "mysql",
       "SERVER_INFO" => "Uptime: 2589441  Threads: 13  Questions: 89348013  Slow queries: 7258017  Opens: 1604  Flush tables: 1  Open tables: 943  Queries per second avg: 34.504",
       "ORACLE_NULLS" => NATURAL,
       "CLIENT_VERSION" => "mysqlnd 5.0.11-dev - 20120503 - $Id: id_here $",
       "SERVER_VERSION" => "5.5.5-10.0.17-MariaDB-1~wheezy-wsrep-log",
       "STATEMENT_CLASS" => [
         "PDOStatement",
       ],
       "EMULATE_PREPARES" => 0,
       "CONNECTION_STATUS" => "localIPhere via TCP/IP",
       "DEFAULT_FETCH_MODE" => BOTH,
     ],
   }

Show db's tables:

显示数据库的表:

>>> $tables = DB::select('SHOW TABLES');
=> [
     {#702
       +"Tables_in_dbname": "table_name_there",
     },
     {#683
       +"Tables_in_dbname": "table_name_there",
     },
     {#699
       +"Tables_in_dbname": "table_name_there",
     },
     {#701
       +"Tables_in_dbname": "table_name_there-20150917-1159",
     },
     {#704
       +"Tables_in_dbname": "contentRepository", */ VIEW TABLE IS THERE!!!! /*
     },
     {#707
       +"Tables_in_dbname": "table_name_there",
     },
     {#684
       +"Tables_in_dbname": "table_name_there",
     },
   ]

Try with normal select:

尝试正常选择:

>>> $results = DB::select('select * from dbname.contentRepository limit 1');
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared (SQL: select * from dbname.contentRepository limit 1)'

Try unprepared query:

尝试未准备好的查询:

>>> DB::unprepared('select * from dbname.contentRepository limit 1')
=> false

Try second time unprepared query:

尝试第二次未准备好的查询:

>>> DB::unprepared('select * from dbname.contentRepository limit 1')
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active.  Consider using PDOStatement::fetchAll().  Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute. (SQL: select * from dbname.contentRepository limit 1)'

Try PDOStatement::fetchAll():

试试 PDOStatement::fetchAll():

>>> DB::fetchAll('select * from dbname.contentRepository limit 1'); 
PHP warning:  call_user_func_array() expects parameter 1 to be a valid callback, class 'Illuminate\Database\MySqlConnection' does not have a method 'fetchAll' in /Users/luca/company/Laravel/dbname/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php on line 296

Try second PDOStatement::fetchAll():

尝试第二个 PDOStatement::fetchAll():

>>> $pdo::fetchAll('select * from dbname.contentRepository limit 1');
  [Symfony\Component\Debug\Exception\FatalErrorException]  
  Call to undefined method PDO::fetchAll()           

Try statement... :

尝试声明...:

>>> $pdos = DB::statement('select * from dbname.contentRepository limit 1')
Illuminate\Database\QueryException with message 'SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared (SQL: select * from dbname.contentRepository limit 1)'

Thank you

谢谢

回答by Tenaciousd93

It seems to work adding

它似乎工作添加

'options'   => [
                \PDO::ATTR_EMULATE_PREPARES => true
            ]

Inside projectName/config/database.phpfile in DB configuration. It will be like this:

projectName/config/database.php数据库配置中的内部文件。它会是这样的:

'mysql' => [
    'driver'    => 'mysql',
    'host'      => env('DB_HOST', 'localhost'),
    'database'  => env('DB_DATABASE', 'forge'),
    'username'  => env('DB_USERNAME', 'forge'),
    'password'  => env('DB_PASSWORD', ''),
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
    'strict'    => false,
    'options'   => [
        \PDO::ATTR_EMULATE_PREPARES => true
    ]
],

Laravel 5.1. Hope it will help!

拉拉维尔 5.1。希望它会有所帮助!

回答by TimoSolo

As per the comments in the accepted answer, running

根据接受的答案中的评论,运行

SET GLOBAL table_definition_cache = 1024

SET GLOBAL table_definition_cache = 1024

in the MariaDB solved the problem.

在 MariaDB 中解决了这个问题。

https://mariadb.com/kb/en/library/server-system-variables/#table_definition_cache

https://mariadb.com/kb/en/library/server-system-variables/#table_definition_cache

回答by Blake

Seems like it's a MySQL Bugthat has been documented.

似乎这是一个已记录在案的MySQL 错误

Edit:

编辑:

Is your model using 'id' as the primary key? I like to set the primary key explicitly in the model even if it is.

您的模型是否使用“id”作为主键?我喜欢在模型中显式设置主键,即使它是。

protected $primaryKey = 'id'; // If different than id, definitely need to set the column here

protected $primaryKey = 'id'; // If different than id, definitely need to set the column here

You can also try commenting out the hasMany()functions and trying again. Sometimes Laravel can do weird things on eagerLoad, especially if there are A LOT of records that it is trying to map to.

您也可以尝试注释掉这些hasMany()函数并重试。有时 Laravel 会在eagerLoad 上做一些奇怪的事情,尤其是当它试图映​​射到很多记录时。