Laravel 5.1如何使用迁移创建MySQL存储过程

16
你好,我正在尝试使用Laravel 5.1迁移创建存储过程。到目前为止,我已经尝试了DB::connection()->getPdo()->exec()、DB::raw()和DB::unprepared(),但都没有成功。以下是我的代码:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use Wryttnapp\Models\User;


class AddCentroidFieldsToUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        DB::connection()->getPdo()->exec("
            ALTER TABLE `users` 
            ADD COLUMN centroid POINT NULL 
            AFTER `avatar`;");

        DB::unprepared("SET @OLD_SQL_MODE=@@SQL_MODE;

            DELIMITER ;;

            DROP PROCEDURE IF EXISTS UPDATE_USER_CENTROID;;

            CREATE PROCEDURE UPDATE_USER_CENTROID(userId INT)
              NOT DETERMINISTIC
            BEGIN
              DECLARE bDone INT;

              DECLARE tempLatLon VARCHAR(100);
              DECLARE counter INT;
              DECLARE firstLatLon VARCHAR(100);
              DECLARE polygonDefinition TEXT;
              DECLARE geometry POINT;

              DECLARE curs CURSOR FOR SELECT DISTINCT CONCAT(`latitude`, ' ', `longitude`) FROM `user_locations` WHERE `user_id` = userId ORDER BY `id` ASC;
              DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;

              OPEN curs;

              SET bDone = 0;
              SET counter = 0;
              SET polygonDefinition = ',';
              FETCH curs INTO tempLatLon;

              WHILE NOT bDone DO
                SET polygonDefinition = CONCAT(polygonDefinition, ',', tempLatLon);

                IF counter = 0 THEN
                      SET firstLatLon = tempLatLon;
                END IF;
                SET counter = counter + 1;

                FETCH curs INTO tempLatLon;
              END WHILE;

              CLOSE curs;

              SET polygonDefinition = CONCAT(polygonDefinition, ',', firstLatLon);
              SET polygonDefinition = SUBSTRING(polygonDefinition, 3);
              SET polygonDefinition = CONCAT('POLYGON((', polygonDefinition, '))');

              SET geometry = ST_Centroid(ST_GeomFromText(polygonDefinition));

              UPDATE `users` SET centroid = geometry WHERE id = userId;
            END;;

            DELIMITER ;
            ");
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        DB::connection()->getPdo()->exec("
            ALTER TABLE `users` DROP COLUMN centroid;
            DROP INDEX centroid_index ON `users`;
            DROP FUNCTION IF EXISTS `UPDATE_USER_CENTROID`;");
    }
}

请帮忙!谢谢!


我批准第一个回复,因为它给了我解决问题的想法。ACM建议的实际上是正确的。此外,在我的情况下,DELIMITER ;;子句会导致问题,并阻止迁移成功执行。我所做的是删除DELIMITER ;;并使用DB::unprepared方法,其中实际函数定义中使用标准分隔符。现在它可以正常工作了。 以下是代码应该如何正确运行的方式:http://pastie.org/private/3xqa6oiqieevhytk9hz1rq - Stoyan Dipchikov
1个回答

29

这是我迄今为止在迁移中执行程序的方式......我相信我在设置分隔符方面遇到了一些麻烦,所以我放弃了它们,并对每个语句使用了不同的unprepared()

$procedure = "
    CREATE PROCEDURE `procedure_name`(procedure_param_1 TEXT, procedure_param_2 TEXT)
    BEGIN
         // Your SP here
    END
";

DB::unprepared("DROP procedure IF EXISTS procedure_name");
DB::unprepared($procedure);

看起来似乎有关联:Laravel migration raw sql error


@acm,我能否运行create procedure并在DB语句上运行? - er.irfankhan11
@er.irfankhan11,你可以。 - steven7mwesigwa

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