Как создать хранимые процедуры MySQL из PHP?

Я написал PHP-скрипт миграции базы данных, который зацикливает список файлов SQL и выполняет их содержимое. Это должно помочь автоматизировать настройку и обновления проекта. Теперь я получаю такие ошибки:

mapCoursesToSport.sql: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER |
DROP PROCEDURE IF EXISTS mapCoursesToSport|
CREATE PROCEDURE mapCo' at line 1

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

Итак, как я могу определить хранимые процедуры MySQL из PHP? (Или, может быть, еще больше: как это SDELIMITER быть обработано?)


person automatix    schedule 22.04.2013    source источник
comment
stackoverflow.com/a/5025730/2153758 Вы там прокомментировали, в ответе ниже говорится, что вам нужно передать каждую переменную один за другим до mysql(i)_query вместо использования запятых.   -  person bwoebi    schedule 22.04.2013
comment
Спасибо за подсказку, но у меня это не работает. Мне нужны разделители в моих хранимых процедурах. Поэтому я не могу просто удалить их из кода. Если я это сделаю, процедуры не будут созданы.   -  person automatix    schedule 23.04.2013
comment
Вам не нужны разделители? Точки с запятой должны передаваться как есть ... и не завершать запрос одним разделителем   -  person bwoebi    schedule 23.04.2013
comment
Нет, я писал, что мне действительно нужны разделители ... Но все равно сейчас у меня работает обходное решение с отключением DELIMITERs. Моя ошибка заключалась в том, что я закомментировал не только определенные строки разделителей (DELIMITER $$), но также строку с END$$ и, кроме того, забыл заменить разделитель $$ в первой строке (DROP PROCEDURE IF EXISTS mapCoursesToSport$$) точкой с запятой. Рабочая версия выглядит так: DROP PROCEDURE IF EXISTS mapCoursesToSport; ... END, так что очень похоже на код в комментарии, который вы связали ... :) Спасибо!   -  person automatix    schedule 23.04.2013
comment
возможный дубликат Как вставить / создать хранимые процедуры в mySQL из PHP?   -  person p.s.w.g    schedule 23.04.2013


Ответы (1)


Вы можете использовать собственные функции PHP mysqli::query и mysqli::prepare в качестве альтернативы для создания хранимой процедуры:

http://php.net/manual/en/mysqli.quickstart.stored-procedures.php

Использование mysqli :: multi_query также работает, но с ним немного сложнее справиться, поскольку вам может потребоваться заранее подсчитать количество запросов, которые нужно выполнить, прежде чем выполнять их один за другим (при условии, что последний разделитель запросов не является обязательным, подсчет запросов может быть утомительным)

http://php.net/manual/en/mysqli.multi-query.php

    <?php
    // Using mysqli extension below in object-oriented mode 
    // after having executing queries 
    // with mysqli::multi_query

    do {
        $queryResult = $mysqli->use_result();
        unset($results);
        while ($result = $queryResult->fetch_array(MYSQLI_ASSOC)) {
            $results[] = $result;
        }
        $queryResult->close();

        if ($mysqli->more_results()) {
            $mysqli->next_result();
        }

        $queryCount--;
    } while ($queryCount > 0);

P.S .: Причина, по которой я не использую ни mysqli:more_results, ни mysqli:next_result в качестве оператора цикла, заключается в том, что некоторый запрос может быть выполнен правильно без возврата какого-либо результата. В таком случае мы не хотим прерывать цикл до того, как все запросы будут выполнены.

person Thierry Marianne    schedule 22.04.2013
comment
Спасибо за ваш ответ! Я не очень понимаю, как это должно работать ... Что ты передаешь multi_query? Как вы определяете queryCount? Где / как вы используете массив $results? - person automatix; 22.04.2013
comment
Все запросы, используемые для создания процедуры, следует передавать в multi_query. Количество запросов можно определить с помощью implode on; (если определено как разделитель запроса) строки вашего запроса, хранящейся в переменной, переданной в mysql_multi_query. Я ввел массив результатов, чтобы охватить общий случай (когда не нужно создавать процедуру, а выполнять несколько запросов, возвращающих результаты). Следуйте документации, указанной в первой ссылке, так как она более проста в использовании. - person Thierry Marianne; 22.04.2013
comment
Спасибо за подробные объяснения! - person automatix; 23.04.2013
comment
Я дал +1 за ваш ответ, потому что он действительно подробный и содержит пример, но я не принял его, так как я уже нашел ответ bwoebi's comment. См. этот комментарий. - person automatix; 23.04.2013
comment
Спасибо! Не могли бы вы отредактировать свой вопрос и дать правильный ответ (или ссылку, указывающую на него) в дополнительном абзаце * EDIT *? - person Thierry Marianne; 23.04.2013