13

Có cách nào để tạo các thủ tục MYSQL được lưu trữ trong một di chuyển Laravel 4 không?Tạo quy trình MYSQL trong Laravel 4 Di chuyển

Ví dụ, đây là một câu hỏi thế hệ thủ tục đơn giản được lưu trữ như là một chuỗi (thông qua một 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)); 

Khi chạy này trong chức năng của di cư up() tôi nhận được lỗi này:

enter image description here

Trả lời

26

Có hai vấn đề lớn với mã của bạn

  1. DELIMITER không phải là câu lệnh sql hợp lệ. Nó chỉ là một lệnh khách hàng MySql. Vì vậy, chỉ cần không sử dụng nó. BTW lỗi bạn nhận được sẽ cho bạn biết chính xác điều đó.
  2. Bạn không thể sử dụng DB::statement để thực thi mã CREATE PROCEDURE vì mã này sử dụng câu lệnh đã chuẩn bị source code for Connection. Bạn có thể sử dụng PDO exec()DB::connection()->getPdo()->exec() thay

đó đang được nói một sự chuyển đổi mẫu cho tưởng tượng tags bảng có thể trông như thế này

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

Chỉ cần đề cập đến, một người nào đó trên diễn đàn Laravel đã chỉ ra rằng bạn thậm chí không cần sử dụng đối tượng PDO, bạn có thể gọi 'DB :: không chuẩn bị ($ sql) 'và nó cũng sẽ hoạt động. Chắc chắn nó có thể sôi xuống đến cùng một điều cuối cùng, nhưng ít mã :) – Johannes

11

Đối với đồng dev tìm kiếm các liên kết trong laravel đề cập bởi @ Johannes.

Any way to create MYSQL Procedures in Migrations? được trả lời bởi @aheissenberger.

tôi sử dụng này và nó hoạt động tốt đối với tôi:

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

Để gọi một thủ tục trong mã của bạn:

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

nếu bạn mong đợi một bảng kết quả:

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

nếu bạn mong đợi các biến:

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