2011-01-01 5 views
5

Mam wiele procedur przechowywanych dokonanych za pomocą środowiska roboczego MySQL. Działają dobrze, gdy używają środowiska roboczego MySQL do umieszczenia ich w moim testowym DB.Jak wstawiać/tworzyć procedury składowane w mySQL z PHP?

Teraz przygotowuję skrypty kreacji DB do wdrożenia, i to jest jedyna, która sprawia mi kłopot. Kiedy używam powłoki linii poleceń/mysql, skrypt działa doskonale. Dopiero gdy użyję interfejsu PHP mysql (i) do wykonania skryptu - to się nie powiedzie. Bez komentarza.

Używam skryptów tworzenia procedur, ponieważ generuje mi workbench MySQL; to znaczy, że ma ten wzór:

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

na początku skryptu, a następnie powtórzenie dla każdej procedury:

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

... procedura idzie tu

; 
END$$ 
DELIMITER ; 

tego skryptu działa dobrze, jeśli działa z poziomu MySQL Workbench. Działa również dobrze, jeśli spróbuję tego samego z linii poleceń mysql. Ale nie wykonuje niczego, gdy wykonuję go za pośrednictwem interfejsu mysqli PHP (wykonując go za pomocą mysqli_multi_query, co działa dobrze dla innych skryptów tworzących i wypełniających DB). W interfejsie nie jest zwracany błąd, brak wyników (!). Wszystko, co otrzymuję, to "fałsz" i to wszystko. kod błędu wynosi 0, brak komunikatu o błędzie.

To dla mnie wielki WTF, i mam nadzieję, że możesz wskazać mi właściwy kierunek - jak mogę to naprawić i zainstalować procedury z PHP?

PS: dostęp do konta root/administratora jest podany i zweryfikowany (w końcu właśnie utworzyłem bazę danych z tym samym połączeniem, utworzonymi użytkownikami, wstawionymi tabelami itd.).

+0

Spróbuj usunąć użycie 'dbname'. Spróbuj także uruchomić, jeśli używasz polecenia mysqli_query. – Knubo

+0

Usunąłem tę instrukcję USE, bez efektu. mysqli_query również się nie powiedzie - iw tym przypadku jest oczywiste, dlaczego: ciąg zawiera wiele instrukcji, więc jeśli * działał * poprawnie, zwracałby wiele wyników - których mysqli_query nie obsługuje. - w przypadku innych skryptów funkcja mysqli_multi_query działa idealnie dobrze, zwracając jeden wiersz wyników dla każdej instrukcji. (puste wiersze na sukces, Uwaga: 1051 linii jako reakcja na POKAŻ OSTRZEŻENIA, - wszystko zgodnie z oczekiwaniami). – foo

+0

Zbliżam się - nie ma rozwiązania, ale diagnoza. DELIMITER wydaje się być zaimplementowany po stronie klienta (!). – foo

Odpowiedz

5

Nie testowałem, ale nie zdziwi mnie, że mysqli_multi_query() spodziewałem się mieć taki sam ogranicznik każdego zapytania. Spróbuj spakować tworzenie składowanej procedury w jednym zapytaniu bez modyfikatora DELIMITER?

Więc zamiast

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

    ; 
    END$$ 
    DELIMITER ; 
'); 
?> 

Wystarczy zrobić to

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

i powiedzieć nam, czy to działa :)

+2

To działa, w pewnym sensie. Jak pisałem wcześniej, DELIMITER wydaje się być zaimplementowany po stronie klienta, a interfejs PHP mysql (i) wydaje się brakować niektórych części implementowanych przez klientów mySQL - jak DELIMITER. Wygląda na to, że DELIMITER w ogóle nie implementuje. Przesyłając procedury oddzielnie i bez DELIMITER działa. Jednak nie sądzę, aby ręczne przepisywanie procedur było wciąż dobrym rozwiązaniem. To dość wiele rutyny i będzie więcej w przyszłości. Potrzebuję czegoś, co działa * z * narzędziami, które otrzymuję, a nie przeciw. Ale dzięki za pomysł, może to pomóc innym. – foo

+1

Dziękuję, miałem ten sam problem, próbując utworzyć i wykonać procedurę przechowywaną z mysqli_multi_query i działało to od HeidiSQL, jednak kiedy wykonałem ten sam kod z PHP, to wystąpił błąd. Usunąłem moje instrukcje DELIMETER, a każda linia podziała i działała idealnie. DZIĘKI! : D – Jared

+0

Pytanie: Jak sprawdzić, czy storedProcedure istnieje już z PHP? –

-3

separatorem jest coś, że aplikacja kliencka mysql faktycznie korzysta. Uważam, że aplikacja kliencka jest odpowiedzialna za dzielenie zapytań wysyłanych do Mysql. Tak na przykład robi PHPMyAdmin.

Zamiast spędzać całą noc na pisaniu skryptu do parsowania MySQL na zapytania, użyj kodu, który napisałem.Znajdziesz go w funkcji scriptToQueries tutaj:

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

ENJOY

EDIT: Ponieważ pisząc tę ​​odpowiedź I przenieśli kod do bezpłatnej platformie Q, w którym można studiować kod: https://github.com/EGreg/Platform/blob/master/platform/classes/Db/Mysql.php#L824

+0

, które poszły prosto we właściwym kierunku. dzięki! – foo

+4

Łącze odwołuje się do strony chronionej hasłem '.htaccess' /' .htpasswd'. – automatix

+0

Dobrze, spróbujcie teraz –

0

Podsumowując:

separatorem jest realizowane po stronie klienta, a nie po stronie serwera.

Jeśli masz dobry sterownik lub API, może to zająć. PHP mysql/mysqli, od teraz nie.

Jeśli musisz użyć innego ogranicznika (np. Z powodu pojawienia się domyślnego separatora wewnątrz skryptów), musisz samodzielnie kodować/uciec się z SQL lub rozdzielić go, aby nie trzeba było zmieniać ogranicznika. Brak pomocy z PHP tutaj.