13

Esiste un modo per generare stored procedure MYSQL in una migrazione di Laravel 4?Creazione della procedura MYSQL in Laravel 4 Migrazioni

Ad esempio, ecco una semplice query generazione procedura memorizzata come stringa (tramite un 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)); 

quando esegue questo in funzione di una migrazione up() ottengo questo errore:

enter image description here

risposta

26

Ci sono due problemi principali con il codice

  1. DELIMITER non è un'istruzione SQL valida. È solo un comando client MySql. Quindi non usarlo. BTW l'errore che ottieni ti dice esattamente questo.
  2. Non è possibile utilizzare DB::statement per eseguire il codice CREATE PROCEDURE perché utilizza l'istruzione preparata source code for Connection. È possibile utilizzare DOP exec()DB::connection()->getPdo()->exec() invece

Detto questo una migrazione di esempio per immaginario tags tabella potrebbe assomigliare a questo

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

Volevo solo dire che qualcuno nei forum Laravel ha sottolineato che non è nemmeno necessario utilizzare l'oggetto PDO, è sufficiente chiamare 'DB :: unprepared ($ sql)' e funzionerà altrettanto bene. Certo, probabilmente si riduce alla stessa cosa alla fine, ma meno codice :) – Johannes

11

Per collega dev cerca il link in laravel citato da @Johannes.

Any way to create MYSQL Procedures in Migrations? ha risposto con @aheissenberger.

Io uso questa e funziona bene per me:

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

Per chiamare una procedura nel codice:

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

se vi aspettate un tabella risultante:

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

se si prevedono variabili:

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