mysql multi_query периодически терпит неудачу - PullRequest
6 голосов
/ 15 сентября 2011
function cpanel_populate_database($dbname) 
{ 
     // populate database
     $sql = file_get_contents(dirname(__FILE__) . '/PHP-Point-Of-Sale/database/database.sql');
     $mysqli->multi_query($sql);

     $mysqli->close();
 }

Файл sql является прямым экспортом из phpMyAdmin, и около 95% времени выполняется без проблем, все таблицы создаются и данные вставляются. (Я создаю базу данных с нуля)

В остальных 5% создается только первая таблица или иногда первые 4 таблицы, но ни одна из других таблиц не создается (существует 30 таблиц).

Я решил НЕ использовать multi_query, потому что он кажется ошибочным и посмотреть, если ошибка возникает, просто используя mysql_query в каждой строке после точки с запятой. Кто-нибудь сталкивался с проблемой, как это?

Ответы [ 4 ]

12 голосов
/ 23 сентября 2011

Быстро и эффективно

system('mysql -h #username# -u #username# -p #database# < #dump_file#');
2 голосов
/ 23 сентября 2011

Я видел похожие проблемы при использовании multi_query с запросами, которые могут создавать или изменять таблицы. В частности, я склонен получать ошибки InnoDB 1005, которые, похоже, связаны с внешними ключами; похоже, что MySQL не завершает полностью одну инструкцию перед переходом к следующей, поэтому внешним ключам не хватает надлежащего референта.

В одной системе я разбил проблемные высказывания на свои собственные файлы. В другом я действительно запускаю каждую команду отдельно, разделяя точки с запятой:

function load_sql_file($basename, $db) {
    // Todo: Trim comments from the end of a line
    log_upgrade("Attempting to run the `$basename` upgrade.");

    $filename = dirname(__FILE__)."/sql/$basename.sql";
    if (!file_exists($filename)) {
        log_upgrade("Upgrade file `$filename` does not exist.");
        return false;
    }

    $file_content = file($filename);
    $query = '';
    foreach ($file_content as $sql_line) {
        $tsl = trim($sql_line);
        if ($sql_line and (substr($tsl, 0, 2) != '--') and (substr($tsl, 0, 1) != '#')) {
            $query .= $sql_line;
            if (substr($tsl, -1) == ';') {
                set_time_limit(300);
                $sql = trim($query, "\0.. ;");
                $result = $db->execute($sql);
                if (!$result) {
                    log_upgrade("Failure in `$basename` upgrade:\n$sql");
                    if ($error = $db->lastError()) {
                        log_upgrade("$error");
                    }

                    return false;
                }

                $query = '';
            }
        }
    }

    $remainder = trim($query);
    if ($remainder) {
        log_upgrade("Trailing text in `$basename` upgrade:\n$remainder");
        if (DEBUG) trigger_error('Trailing text in upgrade script: '.$remainder, E_USER_WARNING);
        return false;
    }

    log_upgrade("`$basename` upgrade successful.");
    return true;
}
0 голосов
/ 19 сентября 2011

Я думаю, что подход разбивки файла SQL на одиночные запросы был бы хорошей идеей. Даже если это только для целей сравнения (чтобы увидеть, если это решает проблему).

Кроме того, я не уверен, насколько велик ваш файл - но у меня была пара случаев, когда файл был невероятно большим, и разбиение его на партии делало свою работу.

0 голосов
/ 19 сентября 2011

Я никогда не прибегал к множественным запросам.Когда мне понадобилось что-то подобное, я перешел на mysqli .Кроме того, если вам не нужны какие-либо результаты из запроса, передача сценария в mysql_query также будет работать.Вы также получите эти ошибки, если есть экспорты в неправильном порядке, которые конфликтуют с таблицами требований для внешних ключей и другими.

...