Вопрос

У меня есть несколько сохраненных процедур, сделанных с помощью Workbench MySQL. Они работают отлично, когда используют MySQL Workbench, чтобы поместить их в мой тест DB.

Теперь я готовлю сценарии создания БД для развертывания, и это единственный, что дает мне проблемы. Когда я использую командную строку / оболочку MySQL, сценарий отлично работает. Только когда я использую интерфейс PHP MySQL (i) для выполнения скрипта - он не работает. Без комментариев.

Я использую сценарии создания процедуры, поскольку для меня генерирует Workbench MySQL; то есть у него есть этот шаблон:

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

В начале сценария, затем повторяя для каждой процедуры:

DELIMITER $$
USE `dbname`$$
CREATE PROCEDURE `procname`(IN inputparameters)
BEGIN

... Процедура идет сюда

;
END$$
DELIMITER ;

Этот скрипт работает нормально, если запустить из MySQL Workbench. Он также работает нормально, если я попробую то же самое из MySQL Commandline. Но это не может ничего достичь, когда я выполняю его через интерфейс PHP MySQLI (выполняя его с помощью mysqli_multi_query, что прекрасно работает для других сценариев, создающих и заполняет DB). В интерфейсе нет ошибки, нет результатов (!). Все, что я получаю, это «ложь», и это все. Код ошибки составляет 0, нет сообщения об ошибке.

Это большой WTF для меня, и я надеюсь, что вы сможете указать мне в правильном направлении - как я могу исправить это и установить процедуры с PHP?

PS: Доступ к корнеу/администратору дается и проверяется (в конце концов, я только что создал DB с тем же соединением, создал пользователей, вставленные таблицы и т. Д.).

Это было полезно?

Решение

Я не тестировал, но я не удивлюсь mysqli_multi_query() ожидая иметь одинаковый разделитель каждой запросы. Попробуйте упаковать сохраненную процедуру создания в один запрос, не используя модификатор разделителя?

Так что вместо

<?php
$results = mysqli_multi(
    'DELIMITER $$
    USE `dbname`$$
    CREATE PROCEDURE `procname`(IN inputparameters)
    BEGIN
    ... procedure goes here

    ;
    END$$
    DELIMITER ;
');
?>

Просто сделай это

<?php
$result = mysqli_query('CREATE PROCEDURE `procname`(IN inputparameters) BEGIN ...; END');

И скажите нам, работает ли это :)

Другие советы

Подвести итог:

Разделитель реализован клиентской стороной, а не сервер.

Если у вас есть хороший водитель или API, это может позаботиться об этом. Php mysql / mysqli, на данный момент нет.

Если вам нужно использовать другой разделитель (например, потому что разделитель по умолчанию появляется внутри сценариев), вы должны кодировать/избежать SQL самостоятельно или разбить его, чтобы вам не нужно было менять разделитель. Нет помощи от PHP здесь.

Разделитель - это то, что на самом деле использует клиентское приложение MySQL. Я считаю, что клиентское заявление несет ответственность за нарушение запросов, которые оно отправляет в MySQL. Это то, что делает phpmyadmin, например.

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

http://wush.net/svn/luckyapps/pie/trunk/framework/classes/db/mysql.php

НАСЛАЖДАТЬСЯ

Изменить: с момента написания этого ответа я перенес код в бесплатную платформу Q, в которой вы можете изучать код: https://github.com/egreg/platform/blob/master/platform/classes/db/mysql.php#l824

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top