七、存储过程:就是具有名字的一段代码,用来完成一个特定的功能。实现了SQL代码的封装。

|--- MySQL中的变量:
          1. 系统变量:(默认是局部变量)
            全局变量:global关键字
            会话变量:也就是局部变量,session关键字
             
            |--- 查看所有系统变量  show global|【session】variables;
                  SHOW GLOBAL VARIABLES;
                  SHOW 【session】 VARIABLES;

            |--- 查看指定的系统变量的值  select @@global|【session】系统变量名;
                  SELECT @@session.tx_isolation;
                  SELECT @@global.autocommit;

            |--- 为某个系统变量赋值
                  方式一:set global|【session】系统变量名=值;
                          SET GLOBAL autocommit = 0;
                          SET SESSION tx_isolation  = 'read-committed';

                  方式二:set @@global|【session】.系统变量名=值;
                         SET @@global.autocommit = 0;
                  

          2. 自定义变量:
            用户变量: 针对于当前会话(连接)有效,作用域同于会话变量,重启失效
               |--- 声明与赋值
                #方式一: 
                  SET @变量名 =| := 值;
                  SELECT @变量名:=值;

                  SET @m= 1;#创建赋值变量的三种方式
                  SET @n:=2;
                  SELECT @sum:=21;

                  SELECT @sum;#显示变量值

                #方式二:
                  SELECT 字段 INTO @变量名
                  FROM 表;
               
                  
            局部变量:仅仅在定义它的begin end块中有效(相当于花括号里面)
                    declare 只能用于存储过程或函数,必须写在begin end 之间的第一句话
               |--- 创建:DECLARE 变量名 类型 【DEFAULT 值】;
               |--- 赋值,同用户变量
                  DECLARE m INT DEFAULT 1;
                  DECLARE f CHAR;


      |--- 存储过程的使用
         1.创建:类似于函数的定义过程
          CREATE PROCEDURE 存储过程名(参数列表)
          BEGIN
            存储过程体(一组合法的SQL语句)
          END

         2.参数列表,包含 参数模式(输入、返回) + 参数名 + 参数类型
            举例:in id varchar(20)

            1、参数模式:
                in:调用该存储过程需要的传入值
                out:存储过程的返回值
                inout:该参数既需要传入值,又可以返回值

            2、如果存储过程体仅仅只有一句话,begin end可以省略
            存储过程体中的每条sql语句的结尾要求必须加分号。
            
            3、delimiter 重新设置结束符号(针对于cmd需要输入多条语句才结束的解决)
            语法:delimiter 结束标记
                  delimiter $  此后$既代表语句的结束符号

         3.调用: call myfun(参数列表)$

         4.删除存储过程:drop procedure 存储过程名

         5.显示存储过程的所有信息: SHOW CREATE PROCEDURE myfun;

    |--- 实际的使用一直报错:几个坑
        ① 存储过程的定义,必须在cmd里面输入
        ② begin end 里面的语句必须要带;正常的语法规则
        ③ 开始前设置好 delimiter 结束符号

    |-- 空参使用存储过程:每调用一次,往 infor 表中插入一行数据。
        DELIMITER $
        CREATE PROCEDURE myfun()
        BEGIN
        INSERT INTO infor(subjects,total,name_new) VALUE('骑车',3000,100);
        END $

        call myfun()$

    |-- in模式使用,实现输入部门编号,查找所有该部门员工的信息
        DELIMITER $
        CREATE PROCEDURE myfound(IN department INT)
        BEGIN
        SELECT d.*,e.*
        FROM employees e
        JOIN departments d
        ON d.department_id = e.department_id
        WHERE  department= e.department_id;
        END $

        call myfound()$


    |-- INOUT模式的使用,输入输出的载体是同一个变量
    
      |-- 先介绍 @ 的用处
        @n,代表n是变量名,如果你不加的话,会认为这是一个列名,但是这列不存在,就报错了;
        1 存储过程如果传进一个参数 int_id,值为1,则在存储过程中int_id和@int_id的值都是1
        2 如果在存储过程中 set @int_id2=1; 则@int_id2=1, int_id2无关
        3 如果在存储过程中 set int_id3=1,则@int_id3=NULL, int_id2 =1
        4 @int_id3不需要declare就可以使用,而int_id3必须先定义

      |-- 示例,使用这个来实现对a b 的改变
        DELIMITER $
        CREATE PROCEDURE myfun(INOUT mynumber INT,INOUT mynumber2 INT)
        BEGIN
          #直接set表示这两个变量已经存在是直接赋值
          SET mynumber = mynumber * 5 ;
          SET mynumber2 = mynumber2 * 2 ;
        END $

        SET @a = 4$
        SET @b = 8$
        #@a,@b,表示传入的是变量a,b的值
        CALL myfun(@a,@b)$
        SELECT @m,@n$