MySQL存储过程实例

(作者:陈玓玏)

定义

存储过程在我的理解里,类似函数的定义,设定好了函数的输入、输出参数、类型,写好了流程,存在数据库里,想用的时候随时可以调用,不需要重新写sql语句,效率很高。而且一般的sql语句间没有逻辑控制,利用存储过程却可以完成很复杂的逻辑控制,加上优化的sql算法,灵活性和功能性都大大提高。

存储过程的结构

  1. 语法:CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型…]]) [特性 …] 过程体

  2. 参数
    存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用”,”分割开。MySQL存储过程的参数用在存储过程的定义,共有三种参数类型,IN,OUT,INOUT:
    IN参数的值必须在调用存储过程时指定,在存储过程中修改该参数的值不能被返回,为默认值
    OUT:该值可在存储过程内部被改变,并可返回
    INOUT:调用时指定,并且可被改变和返回

  3. 在哪里定义?在哪里执行?
    我用的是MySQL-Front,在数据库名上点击右键,新建过程就可以创建存储过程,在数字1标记的地方点击右键,新建过程,创建存储过程,在数字2标记的地方调用存储过程,当然,也可以通过python连接数据库来调用,在数字3标记的地方查看运行结果。
    MySQL存储过程实例_第1张图片
  4. 有例子吗?
-- 输入参数例子
CREATE PROCEDURE in_param(IN p_in int)   #创建一个存储过程,只定义了输入参数
    BEGIN
    SELECT p_in;
    SET p_in=2;
    SELECT p_in;
    END;

分别调用以下三句话:

SET @p_in=1;
CALL in_param(@p_in);
SELECT @p_in;

输出结果分别是:1,2,1

 -- 输出参数例子
 CREATE PROCEDURE out_param(OUT p_out int)
    BEGIN
      SELECT p_out;
      SET p_out=2;
      SELECT p_out;
    END;

分别调用以下命令:

 SET @p_out=1;
CALL out_param(@p_out);
SELECT @p_out;

输出结果分别是:
空,2,2

-- INOUT参数例子:
CREATE PROCEDURE inout_param(INOUT p_inout int)
    BEGIN
      SELECT p_inout;
      SET p_inout=2;
      SELECT p_inout;
    END;

分别调用以下命令:

SET @p_inout=1;
CALL inout_param(@p_inout) ;
SELECT @p_inout;

输出结果分别是:
1,2,2

五、有没有更完整的例子?
带if else语句的存储过程:


 CREATE DEFINER=`root`@`localhost` PROCEDURE `proc3`(IN parameter int)
BEGIN
    DECLARE var int;
    SET var=parameter+1;
    IF var=0 THEN
      INSERT INTO mysql_study.score VALUES (17);
    END IF ;
    IF parameter=0 THEN
      UPDATE mysql_study.score SET degree=degree+1;
    ELSE
      UPDATE mysql_study.score SET degree=degree+2;
    END IF ;
  END;

调用

SET @parameter=1;
CALL proc3(@parameter);

结果:
由于设置的输入参数为1,则表mysql_study.score中所有的degree值加2。

带循环语句的存储过程:(MySQL没有for循环,只有WHILE-DO…END-WHILE、REPEAT…END REPEAT和LOOP…END LOOP)

CREATE DEFINER=`root`@`localhost` PROCEDURE `proc7`(In v INT)
BEGIN
      DECLARE v INT;
      SET v=0;
      LOOP_LABLE:LOOP
        -- INSERT INTO mysql_study.score (degree) VALUES (v);
                select degree from  mysql_study.score where degree>90-v ;
        SET v=v+1;
        IF v >=5 THEN
          LEAVE LOOP_LABLE;
        END IF;
      END LOOP;
    END;

调用

SET @v=4;
CALL proc7(@v);
SELECT @v;

输出结果:有五次输出,分别是输出>85、86、87、88、89的所有分数列表。

六、输入参数为可以为list变量吗?
可是可以,但是貌似有点麻烦。
参考地址:https://segmentfault.com/q/1010000003003758,我自己没试过,但是看别人是这么回答的,下次有时间试一下。上面的代码都是可用的,我自己修改、测试通过了的。

create procedure sp_split_string
(
@string NVARCHAR(4000)
)
AS
BEGIN
DECLARE @object_id nvarchar(500)
DECLARE @i INT
DECLARE @len INT
print @string
IF (@string IS NULL) OR (LTRIM(@string) = '')
RETURN

WHILE CHARINDEX(',',@string) > 0
    BEGIN
        SET @len = LEN(@string)
        SET @i = CHARINDEX(',', @string)
        SET @object_id = LEFT(@string, @i-1)

        INSERT INTO a (id) VALUES (@object_id)--少做修改,改成需要的sql语句即可
        SET @string = RIGHT(@string, @len - @i)
    END
SET @object_id = @string
INSERT INTO a (id) VALUES (@object_id)--少做修改,改成需要的sql语句即可
END
go

–测试

-- select * from a
-- exec sp_split_string '102,103,105,106,107,108,200,500,306,408'
-- select * from a

Oracle的,也没测试过:
https://blog.csdn.net/weeknd/article/details/78412668,https://blog.csdn.net/weeknd/article/details/78412668

-- 创建数组对象
create or replace type tables_array as varray(100) of varchar2(32);
/

-- 测试用存储过程
create or replace procedure test_in_list(
--参数区域
    objlist in tables_array,
    message out varchar2
) is
--变量区域
begin
--执行区域
  for i in objlist.first .. objlist.last loop
    message:=message||objlist(i)||',';
  end loop;
  commit;
end test_in_list;

如果有同学知道在存储过程中传入list参数的简单方法,也可以留言分享,不过也许直接通过python或者java来调用单次操作的存储过程是最简单的吧。

参考文章:https://www.cnblogs.com/mark-chan/p/5384139.html,https://www.cnblogs.com/mark-chan/p/5384139.html

你可能感兴趣的:(数据挖掘)