2011-01-01 5 views
5

У меня есть несколько хранимых процедур, сделанных с помощью Workbench MySQL. Они отлично работают, когда используют workbench MySQL, чтобы поместить их в тестовую БД.Как вставить/создать хранимые процедуры в mySQL с PHP?

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

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

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 

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

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

... процедура проходит здесь

; 
END$$ 
DELIMITER ; 

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

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

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

+0

Попробуйте удалить использование 'dbname'. Также попробуйте запустить, используя команду mysqli_query. – Knubo

+0

Я удалил это заявление USE, никакого эффекта. mysqli_query тоже не работает - и в этом случае очевидно, почему: строка содержит несколько операторов, поэтому, если она * корректно выполняет *, она возвращает несколько результатов, которые mysqli_query не обрабатывает. - для других скриптов mysqli_multi_query работает отлично, возвращая одну строку результата для каждого оператора. (пустые строки при успехе, Примечание: 1051 строка в качестве реакции на SHOW WARNINGS; - все, как ожидалось). – foo

+0

Я приближаюсь - не решение, а диагноз. DELIMITER, похоже, реализован на стороне клиента (!). – foo

ответ

5

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

Таким образом, вместо

<?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'); 

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

+2

Это работает, вроде. Как я уже писал ранее, DELIMITER, похоже, реализован на стороне клиента, а на интерфейсе mysql (i) PHP, похоже, отсутствуют некоторые части, которые реализуют клиенты mySQL - например DELIMITER. По-видимому, он не реализует DELIMITER. Поэтому отправка процедур выполняется отдельно и без DELIMITER. Тем не менее, я не думаю, что ручная переработка подпрограмм снова и снова является жизнеспособным решением. Это довольно много подпрограмм, и в будущем их будет больше. Мне нужно что-то, что работает * с * инструментами, которые мне даны, а не снова. Но, благодаря этой идее, это может помочь другим. – foo

+1

Спасибо, у меня была такая же проблема, пытаясь создать и выполнить хранимую процедуру из mysqli_multi_query, и она работала с HeidiSQL, однако, когда я выполнил тот же код с PHP, он сделал ошибку. Я удалил свои инструкции DELIMETER, и любая строка разбилась, и она отлично работала. БЛАГОДАРЯ! : D – Jared

+0

Вопрос: Как проверить, существует ли storeProcedure уже с PHP? –

-3

DELIMITER является то, что на самом деле использует MySQL клиентское приложение. Я считаю, что клиентское приложение отвечает за разблокирование запросов, которые он отправляет в Mysql. Например, это делает PHPMyAdmin.

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

http://wush.net/svn/luckyapps/pie/trunk/framework/classes/Db/Mysql.php

ENJOY

EDIT: С момента написания этого ответа я портировать код в свободную Q платформы, в которой вы можете изучить код: https://github.com/EGreg/Platform/blob/master/platform/classes/Db/Mysql.php#L824

+0

, который шел прямо в правильном направлении. благодаря! – foo

+4

Ссылка ссылается на страницу защищенного паролем '.htaccess' /' .htpasswd'. – automatix

+0

хорошо, ребята, попробуйте сейчас –

0

Подводя итог:

DELIMITER осуществляется на стороне клиента, а не на стороне сервера.

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

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

Смежные вопросы