Подтвердить что ты не робот

Создание процедуры 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() я получаю эту ошибку:

enter image description here

4b9b3361

Ответ 1

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

  • DELIMITER не является действительной операцией sql. Это просто клиентская команда MySql. Так что просто не используйте его. Кстати, ошибка, которую вы получите, говорит вам именно об этом.
  • Вы не можете использовать 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');
    }
}

Ответ 2

Для тех, кто ищет ссылку в ларавеле, упомянутой @Johannes.

Любой способ создания MYSQL-процедур в Migrations? ответил @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');