在Laravel 4迁移中创建MYSQL存储过程

17

有没有一种方法可以在Laravel 4迁移中生成存储的MYSQL过程?

例如,这里有一个简单的过程生成查询,存储为字符串(通过使用 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

2个回答

32

你的代码存在两个主要问题:

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

8
只是想提一下,Laravel论坛上的某个人指出,你甚至不需要使用PDO对象,只需调用 DB::unprepared($sql) 就可以正常工作。虽然最终可能会归结为相同的结果,但代码更简洁 :) - Johannes

13

对于寻找由@Johannes提到的Laravel链接的同行开发人员。

有没有办法在迁移中创建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');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接