2011-01-01 17 views
5

Ich habe eine Reihe von gespeicherten Prozeduren mit der MySQL Workbench gemacht. Sie funktionieren gut, wenn sie die MySQL-Workbench verwenden, um sie in meine Test-DB zu schreiben.Wie man gespeicherte Prozeduren in mySQL aus PHP einfügt/erstellt?

Jetzt bereite ich die DB-Erstellung Skripte für die Bereitstellung vor, und dies ist der einzige, der mir Probleme bereitet. Wenn ich die Befehlszeile/mysql-Shell verwende, funktioniert das Skript sehr gut. Es ist nur, wenn ich die PHP-mysql (i) -Schnittstelle verwende, um das Skript auszuführen - es schlägt fehl. Ohne Kommentar.

Ich benutze die Prozedurenerstellungsskripte, wie MySQL Workbench für mich generiert; das heißt, es dieses Muster hat:

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

zu Beginn des Skripts, dann für jedes Verfahren zu wiederholen:

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

... Prozedur geht hier

; 
END$$ 
DELIMITER ; 

Dieses Skript funktioniert gut, wenn es von MySQL Workbench ausgeführt wird. Es läuft auch gut, wenn ich das gleiche von mysql Kommandozeile versuche. Aber es bringt nichts, wenn ich es über die PHP-mysqli-Schnittstelle ausführe (indem ich es mit mysqli_multi_query ausführe, was gut für die anderen Skripte funktioniert, die die DB erstellen und auffüllen). Es wird kein Fehler auf der Schnittstelle zurückgegeben, keine Ergebnisse (!). Alles, was ich bekomme, ist "falsch", und das ist es. Fehlercode ist 0, keine Fehlermeldung.

Es ist eine große WTF für mich, und ich hoffe, Sie können mir in die richtige Richtung zeigen - wie kann ich das beheben und die Verfahren von PHP installieren?

PS: root/admin Zugriff ist gegeben und verifiziert (schließlich habe ich nur die DB mit der gleichen Verbindung erstellt, Benutzer erstellt, Tabellen eingefügt und so weiter).

+0

Versuchen Sie, die Verwendung 'DBName' zu entfernen. Versuchen Sie auch, auszuführen, wenn Sie den Befehl mysqli_query verwenden. – Knubo

+0

Ich habe diese USE-Anweisung entfernt, keinen Effekt. mysqli_query scheitert auch - und in diesem Fall ist es offensichtlich, warum: Die Zeichenkette enthält mehrere Anweisungen. Wenn sie * korrekt ausgeführt würde, würde sie mehrere Ergebnisse zurückgeben - was mysqli_query nicht behandelt. - Für die anderen Skripte funktioniert mysqli_multi_query völlig fehlerfrei und gibt eine Ergebniszeile für jede Anweisung zurück. (leere Zeilen bei Erfolg, Hinweis: 1051 Zeilen als Reaktion auf WARNUNGEN ERKLÄREN; - alle wie erwartet). – foo

+0

Ich komme näher - keine Lösung, aber eine Diagnose. DELIMITER scheint clientseitig (!) Implementiert zu sein. – foo

Antwort

5

Ich habe nicht getestet, aber ich werde nicht überrascht sein, mysqli_multi_query() erwartet, dass die gleiche Trennzeichen jeder Abfragen haben. Versuchen Sie, die Erstellung der gespeicherten Prozedur in einer einzigen Abfrage zu packen, ohne den DELIMITER-Modifikator zu verwenden?

Also statt

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

    ; 
    END$$ 
    DELIMITER ; 
'); 
?> 

Sie einfach diesen

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

Und uns sagen, ob es funktioniert :)

+2

Das funktioniert, irgendwie. Wie ich zuvor geschrieben habe, scheint DELIMITER clientseitig implementiert zu sein und die PHP mysql (i) -Schnittstelle scheint einige Teile zu fehlen, die die mySQL-Clients implementieren - wie DELIMITER. Es scheint DELIMITER überhaupt nicht zu implementieren. Das Senden der Prozeduren separat und ohne DELIMITER funktioniert. Ich denke jedoch nicht, dass das manuelle Umschreiben der Routinen immer wieder eine praktikable Lösung ist. Es ist eine ganze Reihe von Routinen, und in Zukunft wird es mehr geben. Ich brauche etwas, das * mit * den Werkzeugen, die mir gegeben werden, funktioniert, nicht dagegen. Aber danke für die Idee, das kann anderen helfen. – foo

+1

Danke, ich hatte das gleiche Problem, versuchen zu erstellen, und eine gespeicherte Prozedur von mysqli_multi_query ausführen und es funktionierte von HeidiSQL, aber wenn ich den gleichen Code von PHP ausgeführt wurde, warf es einen Fehler. Ich entfernte meine DELIMETER-Anweisungen und alle Zeilenumbrüche und es funktionierte perfekt. VIELEN DANK! : D – Jared

+0

Frage: Wie überprüfe ich, ob storedProcedure schon existiert, von PHP? –

-3

DELIMITER etwas ist, dass die MySQL-Client-Anwendung tatsächlich verwendet. Ich glaube, dass die Client-Anwendung dafür verantwortlich ist, die Anfragen zu lösen, die sie an Mysql sendet. Das macht zum Beispiel PHPMyAdmin.

Anstatt eine ganze Nacht damit zu verbringen, ein Skript zu schreiben, um MySQL in Abfragen zu parsen, verwende den Code, den ich geschrieben habe.Sie werden es in der scriptToQueries Funktion finden, hier:

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

EDIT GENIESSEN: Da diese Antwort schreiben ich den Code in die freie Q Plattform portiert haben, in dem Sie den Code studieren können: https://github.com/EGreg/Platform/blob/master/platform/classes/Db/Mysql.php#L824

+0

das ging gerade in die richtige Richtung. Vielen Dank! – foo

+4

Der Link verweist auf eine passwortgeschützte Seite ".htaccess"/".htpasswd". – automatix

+0

okay Jungs versuchen jetzt –

0

Um es zusammenzufassen:

DELIMITER ist clientseitige implementiert, nicht serverseitig.

Wenn Sie einen guten Treiber oder eine gute API haben, kann es dafür sorgen. PHP mysql/mysqli, ab sofort nicht.

Wenn Sie ein anderes Trennzeichen verwenden müssen (z. B. weil das Standardtrennzeichen in Skripts angezeigt wird), müssen Sie Ihr SQL selbst verschlüsseln/escape oder es aufteilen, so dass Sie das Trennzeichen nicht ändern müssen. Keine Hilfe von PHP hier.

Verwandte Themen