Laravel 5.1 如何使用迁移创建 MySQL 存储过程
Posted
技术标签:
【中文标题】Laravel 5.1 如何使用迁移创建 MySQL 存储过程【英文标题】:Laravel 5.1 How do you create a MySQL stored procedure with migration 【发布时间】:2016-06-03 12:55:35 【问题描述】:您好,我正在尝试使用 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
方法,其中的实际函数定义使用标准分隔符。现在工作正常。为了正常工作,代码应该如下所示:pastie.org/private/3xqa6oiqieevhytk9hz1rq
【参考方案1】:
到目前为止,这就是我在迁移过程中的处理方式...
我相信我在设置分隔符时遇到了一些问题,所以我删除了它们并为每个语句使用了不同的 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,我可以运行创建过程并通过 DB 语句运行 @er.irfankhan11 ,是的,你可以。以上是关于Laravel 5.1 如何使用迁移创建 MySQL 存储过程的主要内容,如果未能解决你的问题,请参考以下文章
在迁移 laravel 5.1 中设置自动增量字段从 1000 开始
从 5.1 迁移到 5.3 时急切加载关系的 Laravel 错误