【问题标题】:Creating MYSQL Procedure in Laravel 4 Migrations在 Laravel 4 迁移中创建 MYSQL 过程
【发布时间】:2013-08-25 02:33:27
【问题描述】:

有没有办法在 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() 函数中运行此程序时,我收到此错误:

【问题讨论】:

    标签: mysql stored-procedures laravel laravel-4 database-migration


    【解决方案1】:

    您的代码有两个主要问题

    1. DELIMITER 不是有效的 sql 语句。这只是一个 MySql 客户端命令。所以不要使用它。 顺便说一句你得到的错误告诉你。
    2. 您不能使用DB::statement 执行CREATE PROCEDURE 代码,因为它使用准备好的语句source code for Connection。您可以改用 PDO exec() DB::connection()-&gt;getPdo()-&gt;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');
        }
    }
    

    【讨论】:

    • 只是想提一下,Laravel 论坛上有人指出你甚至不需要使用 PDO 对象,你只需调用 DB::unprepared($sql) 就可以了。当然它最终可能归结为同样的事情,但代码更少:)
    【解决方案2】:

    对于寻找 @Johannes 提到的 laravel 中的链接的开发人员。

    Any way to create MYSQL Procedures in 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');
    

    【讨论】:

      猜你喜欢
      • 2017-05-25
      • 2014-08-24
      • 2016-06-03
      • 2019-03-22
      • 2019-03-02
      • 1970-01-01
      • 2014-05-03
      • 2016-12-11
      • 1970-01-01
      相关资源
      最近更新 更多