13

Czy istnieje sposób generowania przechowywanych procedur MYSQL w migracji Laravel 4?Tworzenie procedury MYSQL w Laravel 4 Migracje

Na przykład, oto zapytanie prosty generacja procedura przechowywana jako ciąg (poprzez 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)); 

przy uruchamianiu tego w up() funkcji migracji za otrzymuję ten błąd:

enter image description here

Odpowiedz

26

Występują dwa poważne problemy z kodem

  1. DELIMITER nie jest prawidłowym oświadczeniem SQL. To tylko polecenie klienta MySql. Więc po prostu go nie używaj. BTW błąd, który otrzymasz, mówi dokładnie to.
  2. Nie można użyć kodu DB::statement do wykonania kodu CREATE PROCEDURE, ponieważ używa on przygotowanej instrukcji source code for Connection. Można użyć PDO exec()DB::connection()->getPdo()->exec() zamiast

takiej sytuacji migracja próbki do wyimaginowanej tags tabeli może wyglądać następująco

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

Chciałem tylko wspomnieć, że ktoś na forach Laravel wskazał, że nie musisz nawet używać obiektu PDO, możesz po prostu zadzwonić 'DB :: nieprzygotowany ($ sql)' i będzie działać równie dobrze. Pewnie to prawdopodobnie sprowadza się do tego samego na końcu, ale mniej kodu :) – Johannes

11

Dla kolegi dev poszukuje link w laravel wspomnianym przez @Johannes.

Any way to create MYSQL Procedures in Migrations? odpowiedział @aheissenberger.

używam to i to działa dobrze dla mnie:

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

Aby wywołać procedurę w kodzie:

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

jeśli oczekujesz wynikającą tabeli:

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

jeśli oczekujesz zmiennych:

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