13

Gibt es eine Möglichkeit, gespeicherte MYSQL-Prozeduren in einer Laravel 4-Migration zu generieren?Erstellen von MYSQL-Prozedur in Laravel 4 Migrationen

Zum Beispiel, hier ist eine einfache Prozedur Generation Abfrage als String gespeichert (über ein Heredoc)

$query = <<<SQL 
DELIMITER $$ 
DROP PROCEDURE IF EXISTS test$$ 
CREATE PROCEDURE test() 
BEGIN 
    INSERT INTO `test_table`(`name`) VALUES('test'); 
END$$ 
DELIMITER ; 
SQL; 

    DB:statement(DB::RAW($query)); 

Wenn das Lauf in einer up() Funktion der Migration ich diesen Fehler:

enter image description here

Antwort

26

Es gibt zwei Hauptprobleme mit Ihrem Code

  1. DELIMITER ist keine gültige SQL-Anweisung. Es ist nur ein MySql-Client-Befehl. Also benutz es einfach nicht. BTW der Fehler, den Sie erhalten, sagt Ihnen genau das.
  2. Sie können DB::statement nicht verwenden, um CREATE PROCEDURE Code auszuführen, da es die vorbereitete Anweisung source code for Connection verwendet. Sie können PDO verwenden exec()DB::connection()->getPdo()->exec() statt

Das für imaginäre tags Tabelle eine Probe Migration wie diese für den Link in Laravel von @Johannes erwähnt suchen

class CreateTagsTable extends Migration { 

    /** 
    * Run the migrations. 
    * 
    * @return void 
    */ 
    public function up() 
    { 
     Schema::create('tags', function($table){ 
      $table->increments('id'); 
      $table->string('name')->unique(); 
     }); 
$sql = <<<SQL 
DROP PROCEDURE IF EXISTS sp_insert_tag; 
CREATE PROCEDURE sp_insert_tag(IN _name VARCHAR(32)) 
BEGIN 
    INSERT INTO `tags`(`name`) VALUES(_name); 
END 
SQL; 
     DB::connection()->getPdo()->exec($sql); 
    } 

    /** 
    * Reverse the migrations. 
    * 
    * @return void 
    */ 
    public function down() 
    { 
     $sql = "DROP PROCEDURE IF EXISTS sp_insert_tag"; 
     DB::connection()->getPdo()->exec($sql); 
     Schema::drop('tags'); 
    } 
} 
+5

Ich wollte nur erwähnen, jemand in den Laravel Foren hat darauf hingewiesen, dass Sie nicht einmal das PDO-Objekt verwenden müssen, Sie können einfach 'DB :: unvorbereitet ($ sql)' aufrufen und es wird genauso gut funktionieren. Sicher, es läuft am Ende wahrscheinlich auf dasselbe hinaus, aber weniger Code :) – Johannes

11

Für Kerl dev aussehen könnte gesagt wird.

Any way to create MYSQL Procedures in Migrations? beantwortet von @aheißenberger.

Ich benutze dieses und es funktioniert gut für mich:

public function up() {    
    DB::unprepared('CREATE PROCEDURE get_highscore() BEGIN SET time_zone = \'Europe/Berlin\'; SET @refscore :=0; SELECT * FROM test; END'); 
} 

public function down() { 
    DB::unprepared('DROP PROCEDURE IF EXISTS get_highscore'); 
} 

Um eine Prozedur in Ihrem Code aufrufen:

DB::unprepared('CALL get_highscore()'); 

, wenn Sie erwarten eine Ergebnistabelle:

DB::statement('CALL update_highscore()'); 

Wenn Sie Variablen erwarten:

DB::statement('CALL update_ranking(3,10,@olduser,@newuser)'); 
$dberg = DB::select('select @olduser as old, @newuser as new');