How to get rid of MySQL error 'Prepared statement needs to be re-prepared'

后端 未结 7 1426
夕颜
夕颜 2020-11-27 07:43

I\'ve rewritten my site php-code and added MySQL Stored Procedures.

In my local version everything works fine but after I uploaded my site to hosting server I\'m co

相关标签:
7条回答
  • 2020-11-27 08:03

    In short: Don't use VIEWS in prepared statements.

    This seems to be an on-going issue

    Views are messy to handle with Dynamic SQL

    Earliest Bug was Cannot create VIEWs in prepared statements from 11 years ago. There was a patch put in to address it.

    Another bug report, Prepared-Statement fails when MySQL-Server under load, states that error 1615 is not a bug when the underlying tables are busy. (Really ?)

    While there is some merit to increasing the table cache size (See MySql error when working with a mysql view), it does not always work (See General error: 1615 Prepared statement needs to be re-prepared (selecting mysql view))

    ALTERNATIVES Over a year ago, someone mentioned this in the MySQL Forum (MySql “view”, “prepared statement” and “Prepared statement needs to be re-prepared”).

    Someone came up with the simple idea of not using the view in the prepared statement but using the SQL of view in a subquery instead. Another idea would be to create the SQL used by the view and execute it in your client code.

    These would seems to be better workarounds that just bumping up the table cache size.

    0 讨论(0)
  • 2020-11-27 08:03

    I was getting this same error in Ruby on Rails in a shared hosting environment. It may not be the most secure solution, but disabling prepared statements got rid of the error message for me.

    This can be done by adding the "prepared_statements: false" setting to your database.yml file:

    production:
      prepared_statements: false
    

    This seems like a reasonable solution when you don't have control over the configuration settings on the MySQL server.

    0 讨论(0)
  • 2020-11-27 08:04

    This is a possibility: MySQL bug #42041

    They suggest upping the value of table_definition_cache.

    You can read about re-preparation in the MySQL docs.

    0 讨论(0)
  • 2020-11-27 08:05

    @docwhat's answer seems nice, but on a shared hosting server, not everyone is allowed to touch the table_open_cache or table_definition_cache options.

    Since this error is related to prepared statements, I have tried to 'emulate' those with PDO by providing the following option:

    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, [
        PDO::ATTR_EMULATE_PREPARES => true
    ]);
    

    Note: actually this is in a Laravel 5.6 project, and I added the option in config/database.php:

    'connections' => [
        'mysql' => [
            'driver' => 'mysql',
            'host' => env('DB_HOST', '127.0.0.1'),
            'port' => env('DB_PORT', '3306'),
            'database' => env('DB_DATABASE', 'forge'),
            'username' => env('DB_USERNAME', 'forge'),
            'password' => env('DB_PASSWORD', ''),
            'unix_socket' => env('DB_SOCKET', ''),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'strict' => true,
            'engine' => null,
            'options' => [
                PDO::ATTR_EMULATE_PREPARES => true,
            ],
        ],
        (...)
    ],
    

    I have not tested the impact of emulating prepared statements on the duration of loading my site, but it works against the error SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared I got.

    Update on the performance: the emulated version seems to be slightly faster (32.7±1.4ms emulated, 35.0±2.3ms normal, n=10, p-value=0.027 for two-tailed Student's T-test).

    0 讨论(0)
  • 2020-11-27 08:11

    Issue: 'Prepared statement needs to be re-prepared'

    This issue generally occurs at the time of calling procedure either by using any Computer Language(like Java) or Calling Procedures from the backend.

    Solution: Increase the size of the cache by using (executing) below script.

    Script: set global table_definition_cache = 4000;

    0 讨论(0)
  • 2020-11-27 08:22

    my solutions is to create a routine like this:

    DELIMITER $$
    --
    -- Procedimientos
    --
    DROP PROCEDURE IF EXISTS `dch_content_class_content`$$
    
    CREATE DEFINER=`renuecod`@`localhost` PROCEDURE `dch_content_class_content`(IN $classId INTEGER)
    BEGIN
    -- vw_content_class_contents is a VIEW (UNIONS)
      select * from vw_content_class_contents;
    END$$
    

    I hope this help someone

    0 讨论(0)
提交回复
热议问题