无法通过 Laravel 迁移使用 mysql/mariaDB 功能
Posted
技术标签:
【中文标题】无法通过 Laravel 迁移使用 mysql/mariaDB 功能【英文标题】:Unable to mysql/mariaDB function through Laravel migrations 【发布时间】:2021-06-21 03:32:10 【问题描述】:我正在尝试创建一个mysql存储函数
DROP FUNCTION IF EXISTS getDistance;
DELIMITER $$
CREATE FUNCTION `getDistance`(`lat1` VARCHAR(255), `lng1` VARCHAR(255), `lat2` VARCHAR(255), `lng2` VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
BEGIN
DECLARE distance varchar(255);
SELECT (6371 * acos(cos(radians(lat2)) * cos(radians(lat1)) * cos(radians(lng1) - radians(lng2)) + sin(radians(lat2)) * sin(radians(lat1)))) INTO distance;
if(distance is null) then
return null;
else
return distance;
end if;
END
$$
DELIMITER ;
如果我通过 phpMyAdmin 执行该函数,则工作正常,并且在数据库中创建函数
但是当我尝试运行 Laravel(v6.x) 迁移来创建存储函数时,我遇到了错误
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateStoredFunction extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
DB::unprepared('
DROP FUNCTION IF EXISTS getDistance;
DELIMITER $$
CREATE FUNCTION `getDistance`(`lat1` VARCHAR(255), `lng1` VARCHAR(255), `lat2` VARCHAR(255), `lng2` VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
BEGIN
DECLARE distance varchar(255);
SELECT (6371 * acos(cos(radians(lat2)) * cos(radians(lat1)) * cos(radians(lng1) - radians(lng2)) + sin(radians(lat2)) * sin(radians(lat1)))) INTO distance;
if(distance is null) then
return null;
else
return distance;
end if;
END
$$
DELIMITER ;
');
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
DB::unprepared('DROP FUNCTION IF EXISTS getDistance');
错误
Doctrine\DBAL\Driver\PDO\Exception::("SQLSTATE[42000]: 语法错误或访问冲突:1064 您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册以获取正确的'DELIMITER $$ 附近使用的语法 创建函数
getDistance
(lat1
VARCHAR(255), ' 在第 1 行")
【问题讨论】:
附注:down
尝试删除名为 distance
的函数,但您的函数名为 getDistance
。
双贴:***.com/questions/66780770/…删除两者之一
@brombeer,已删除 2 个中的 1 个,谢谢
【参考方案1】:
DELIMITER
不是有效的 SQL 语句。这只是一个 MySql 客户端命令。所以不要使用它。您得到的错误准确地告诉了您。
你可以像这样在 Laravel 中创建一个存储过程,这将使 DELIMITER
过时
试试这个
class CreateStoredFunction extends Migration
/**
* Run the migrations.
*
* @return void
*/
public function up()
DB::unprepared('
DROP FUNCTION IF EXISTS getDistance;
CREATE FUNCTION `getDistance`(`lat1` VARCHAR(255), `lng1` VARCHAR(255), `lat2` VARCHAR(255), `lng2` VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
BEGIN
DECLARE distance varchar(255);
SELECT (6371 * acos(cos(radians(lat2)) * cos(radians(lat1)) * cos(radians(lng1) - radians(lng2)) + sin(radians(lat2)) * sin(radians(lat1)))) INTO distance;
if(distance is null) then
return null;
else
return distance;
end if;
END
');
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
DB::unprepared('DROP FUNCTION IF EXISTS getDistance');
【讨论】:
一个好的答案应该包括对更改的内容以及它如何解决问题的解释,以便 OP 和任何未来的读者可以从中学习。 if / else 构造也没有任何意义。你可以很容易地做到return distance;
以上是关于无法通过 Laravel 迁移使用 mysql/mariaDB 功能的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有工匠的情况下运行 laravel 迁移(使用代码)