Создание процедуры MYSQL в Laravel 4 Migrations

Есть ли способ сгенерировать хранимые процедуры MYSQL при миграции на Laravel 4?

Например, вот простой запрос генерации процедуры, хранящийся в виде строки (через 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));

При запуске этого в функции миграции up() я получаю эту ошибку:

введите описание изображения здесь


person Johannes    schedule 22.08.2013    source источник


Ответы (2)


В вашем коде есть две основные проблемы

  1. DELIMITER не является допустимым оператором sql. Это просто клиентская команда MySql. Так что просто не используйте это. Кстати ошибка, которую вы получаете, говорит вам именно об этом.
  2. Вы не можете использовать DB::statement для выполнения CREATE PROCEDURE кода, потому что он использует подготовленный оператор исходный код для Connection. Вместо этого вы можете использовать PDO exec() DB::connection()->getPdo()->exec()

При этом образец миграции для воображаемой таблицы tags может выглядеть так

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');
    }
}
person peterm    schedule 23.08.2013
comment
Просто хотел упомянуть, что кто-то на форумах Laravel указал, что вам даже не нужно использовать объект PDO, вы можете просто вызвать DB::unprepared($sql), и он будет работать так же хорошо. Конечно, в конечном итоге все сводится к тому же, но меньше кода :) - person Johannes; 26.08.2013

Для коллег-разработчиков, которые ищут ссылку в laravel, упомянутую @Johannes.

Есть ли способ создать процедуры MYSQL при миграции? ответил @aheissenberger.

Я использую это, и он мне подходит:

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

Чтобы вызвать процедуру в вашем коде:

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

если вы ожидаете результирующую таблицу:

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

если вы ожидаете переменных:

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