Php 在Laravel 5.5中创建MySQL函数

Php 在Laravel 5.5中创建MySQL函数,php,mysql,database,laravel,Php,Mysql,Database,Laravel,我有MySQL 5.6,我需要使用MySQL 5.7函数ST_Distance_Sphere(用于地理定位) 我找到了,它对我来说是正确的(?) 现在我试着在Laravel 5.5中使用它 我把它放在app\Providers\AppServiceProvider.phpboot()函数中 我尝试了DB::statement,DB::raw,DB::unprepared 我试图删除分隔符和$$ $sql = ' DELIMITER $$ DROP FUNCTIO

我有MySQL 5.6,我需要使用MySQL 5.7函数
ST_Distance_Sphere
(用于地理定位)

我找到了,它对我来说是正确的(?)

现在我试着在Laravel 5.5中使用它

我把它放在
app\Providers\AppServiceProvider.php
boot()函数中

我尝试了
DB::statement
DB::raw
DB::unprepared

我试图删除
分隔符
$$

$sql = '
        DELIMITER $$

        DROP FUNCTION IF EXISTS `ST_Distance_Sphere`$$

        CREATE FUNCTION `ST_Distance_Sphere` (point1 POINT, point2 POINT)

            RETURNS FLOAT
            no sql deterministic
            BEGIN
                declare R INTEGER DEFAULT 6371000;
                declare `φ1` float;
                declare `φ2` float;
                declare `Δφ` float;
                declare `Δλ` float;
                declare a float;
                declare c float;
                set `φ1` = radians(y(point1));
                set `φ2` = radians(y(point2));
                set `Δφ` = radians(y(point2) - y(point1));
                set `Δλ` = radians(x(point2) - x(point1));

                set a = sin(`Δφ` / 2) * sin(`Δφ` / 2) + cos(`φ1`) * cos(`φ2`) * sin(`Δλ` / 2) * sin(`Δλ` / 2);
                set c = 2 * atan2(sqrt(a), sqrt(1-a));

                return R * c;
            END$$

        DELIMITER ;
    ';

DB::statement($sql);
我每次都有语法错误。例如:

``Illuminate \ Database \ QueryException (42000)SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe près de 'DELIMITER $$ DROP FUNCTION IF EXISTS `ST_Distance_Sphere`$$ ' à la ligne 1 (SQL: DELIMITER $$ DROP FUNCTION IF EXISTS `ST_Distance_Sphere`$$ CREATE FUNCTION `ST_Distance_Sphere` (point1 POINT, point2 POINT) RETURNS FLOAT no sql deterministic BEGIN declare R INTEGER DEFAULT 6371000; declare `φ1` float; declare `φ2` float; declare `Δφ` float; declare `Δλ` float; declare a float; declare c float; set `φ1` = radians(y(point1)); set `φ2` = radians(y(point2)); set `Δφ` = radians(y(point2) - y(point1)); set `Δλ` = radians(x(point2) - x(point1)); set a = sin(`Δφ` / 2) * sin(`Δφ` / 2) + cos(`φ1`) * cos(`φ2`) * sin(`Δλ` / 2) * sin(`Δλ` / 2); set c = 2 * atan2(sqrt(a), sqrt(1-a)); return R * c; END$$ DELIMITER ; )``

我回答自己的问题

似乎我没有权限删除MySQL函数

因此,我用MySQL版本检查替换了
DROP函数(如果存在)`ST\u Distance\u Sphere`

$mysql_version_check = DB::select(DB::raw('SHOW VARIABLES LIKE "version";'));
$mysql_version = $mysql_version_check[0]->Value;
if (substr($mysql_version,2, 1) < '7' AND substr($mysql_version,4, 1) < '6') {
    $sql = '
        CREATE FUNCTION `ST_Distance_Sphere` (point1 POINT, point2 POINT)

            RETURNS FLOAT
            no sql deterministic
            BEGIN
                declare R INTEGER DEFAULT 6371000;
                declare `φ1` float;
                declare `φ2` float;
                declare `Δφ` float;
                declare `Δλ` float;
                declare a float;
                declare c float;
                set `φ1` = radians(y(point1));
                set `φ2` = radians(y(point2));
                set `Δφ` = radians(y(point2) - y(point1));
                set `Δλ` = radians(x(point2) - x(point1));

                set a = sin(`Δφ` / 2) * sin(`Δφ` / 2) + cos(`φ1`) * cos(`φ2`) * sin(`Δλ` / 2) * sin(`Δλ` / 2);
                set c = 2 * atan2(sqrt(a), sqrt(1-a));

                return R * c;
            END;
    ';

    DB::unprepared($sql);

}
$mysql\u version\u check=DB::select(DB::raw('SHOW VARIABLES LIKE“version”);
$mysql\u version=$mysql\u version\u check[0]->值;
if(substr($mysql\u版本,2,1)<'7'和substr($mysql\u版本,4,1)<'6'){
$sql='1
创建函数“ST_Distance_Sphere”(点1点,点2点)
返回浮动
无sql确定性
开始
声明R整数默认值6371000;
宣布“φ1”浮动;
宣布“φ2”浮动;
宣布Δφ浮动;
声明Δλ浮点数;
宣布浮动;
宣布c浮动;
设置`φ1`=弧度(y(点1));
设置`φ2`=弧度(y(点2));
设置“Δφ”=弧度(y(点2)-y(点1));
设置`Δλ`=弧度(x(点2)-x(点1));
集合a=sin(`Δφ`/2)*sin(`Δφ`/2)+cos(`φ1`)*cos(`φ2`)*sin(`Δλ`/2)*sin(`Δλ`/2);
集合c=2*atan2(sqrt(a),sqrt(1-a));
返回R*c;
结束;
';
DB::unprepared($sql);
}
这有点难看,但似乎有用

编辑
实际上,它只有在第一次执行时才起作用。看起来这个函数可以将mysql函数保存到mysql数据库中。下一次您将出现错误,如“Mysql函数已存在”。您只需对上面的块进行注释。

从错误消息看,您似乎无权删除函数
ST_Distance_Sphere
?尝试通过MySQL客户端运行SQL,我猜您会收到相同的错误消息。@SudiptaMondal我已经尝试在phpmyadmin中运行此命令,但没有收到任何错误消息。@SudiptaMondal我认为您是对的,请参阅下面的答案。谢谢您需要在数据库中创建它,以便访问它。谢谢,实际上我就是这么做的,即使它会导致导出/导入问题(函数已经存在)。如果存在,请添加
DROP函数