无法通过 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 迁移:无法添加外键约束

如何在没有工匠的情况下运行 laravel 迁移(使用代码)

无法使用 laravel 数据库迁移创建外键

laravel 5.4 迁移无法正常工作

SQLSTATE [23000]:完整性约束违规:1452 无法在 laravel 迁移中添加或更新子行

无法使用 Laravel 迁移 [重复]