mysql中如何创建存储过程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql中如何创建存储过程相关的知识,希望对你有一定的参考价值。

参考技术A

-- 创建存储过程DELIMITER $ --声明存储过程的结束符

CREATE PROCEDURE stu_test() --存储过程名称(参数列表)

BEGIN    --开始   -- 可以写多个sql语句       -- sql语句+流程控制  

  END $    --结束 结束符

-- 执行存储过程call stu_test()   --call 存储过程名称(参数)

参数:IN:  表示输入参数,可以携带数据带存储过程中
OUT: 表示输出参数,可以从存储过程中返回结果
INOUT: 表示输入输出参数,两者结合


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

【中文标题】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 ,是的,你可以。

以上是关于mysql中如何创建存储过程的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 存储过程 - 如何引用内部创建的记录集

如何从 PHP 在 mySQL 中插入/创建存储过程?

navicat for MySQL中的 查询编辑器中如何执行存储过程?

错误创建存储过程 MySQL

MySQL创建存储过程(CREATE PROCEDURE)

mysql 存储过程