MySQL存储过程、变量、游标和存储函数

MySQL存储过程

  • 本文用python执行SQL语句。
    导入python库
import json
import pymysql
from pymysql.converters import escape_string
import pandas as pd

连接数据库

#连接数据库
conn=pymysql.connect(
    host="localhost",
    port=3306,#端口号
    user="root",#数据库用户
    password="123456",#数据库密码
    #database="world"#要连接的数据库名称
)
cur=conn.cursor()

跳转到指定数据库

sql = """USE PLJNB"""
cur.execute(sql)
cur.fetchall()

介绍

将SQL语句封装并重用,提高数据处理效率

特点:
  • 封装、复用
  • 可以接收参数,也可以返回数据
  • 减少网络交互,提升效率

创建存储过程

  • 在命令行中,执行创建存储过程的SQL时,需要通过关键字delimiter指定SQL结束符。
  • 例:
    delimiter $$ :表示以该命令行$$为SQL结束符
CREATE PROCEDURE 存储过程名称([参数列表])
BEGIN
	--SQL语句
END;
  • 例:
sql = """
    CREATE PROCEDURE p1()
    BEGIN
        SELECT COUNT(*) FROM student;
    END;
"""
cur.execute(sql)
cur.fetchall()

调用存储过程

CALL 名称([参数]);
  • 例:
sql = """
    CALL p1();
"""
cur.execute(sql)
pd.DataFrame(list(cur.fetchall()),columns=[i[0] for i in cur.description])

查看存储过程

查询指定数据库的存储过程及状态信息
SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = '数据库名'
查询某个存储过程的定义
SHOW CREATE PROCEDURE 存储过程名称;

删除某个存储过程

DROP PROCEDURE [IF EXISTS] 存储过程名称;

变量

系统变量
  • MySQL服务器提供,不是用户定义的,分为全局变量(GLOBAL)、会话变量(SESSION)。
  • 服务重启后,所设置的全局变量会失效,若想不失效,需在/etc/my.cnf中设置。
查看系统变量
  1. 查看所有系统变量:
SHOW [SESSION|GLOBAL] VARIABLES;
  1. 模糊查找变量:
SHOW [SESSION|GLOBAL] VARIABLES LIKE '...'
  1. 查看指定变量:
SELECT @@[SESSION|GLOBAL].系统变量名;
设置系统变量
SET [SESSION|GLOBAL] 系统变量名 =;

SET @@[SESSION|GLOBAL].系统变量名 =;

用户定义变量

  • 用户变量赋值时用:=以区分判断=
  • 用户根据自己需要定义的变量,用"@变量名"定义即可,作用域为当前会话
  • 不需要初始化,也不需要提前声明,不初始化时取值为NULL
用户变量赋值
SET @变量名 =[,@变量名 =]...;

SET @变量名 :=[,@变量名 :=]...;

SELECT @变量名 :=[,@变量名 :=]...;

SELECT 字段名 INTO @变量名 FROM 表名;
用户变量使用
SELECT @变量名;

局部变量

  • 在存储过程内使用的局部变量,需要DECLARE声明
局部变量声明
DECLARE 变量名 变量类型 [DEFAULT...];(变量类型:INTBIGINT)
局部变量赋值
SET 变量名 =;

SET 变量名 :=;

SELECT 字段名 INTO 变量名 FROM 表名...;
  • 例:
sql = """
    CREATE PROCEDURE p2()
    BEGIN
        DECLARE stu_count INT DEFAULT 1;
        SELECT COUNT(*) INTO stu_count FROM student;
        SELECT stu_count;
    END;
"""
cur.execute(sql)
cur.fetchall()

存储过程的参数

参数类别
参数关键字作用
IN该类参数作为输入,也就是需要调用时传入值
OUT该类参数作为输出,也就是该参数可以作为返回值
INOUT既可以作为输入参数,也可以作为输出参数
含参存储过程的创建
CREATE PROCEDURE 存储过程名称([IN/OUT/INOUT 参数名 参数类型])
BEGIN
  --SQL语句
END;
  • 例:
sql = """
    CREATE PROCEDURE p4(IN age INT,OUT age_rank VARCHAR(10))
    BEGIN
        IF age >= 23 THEN
            SET age_rank := '99年';
        ELSEIF age >= 22 THEN
            SET age_rank := '00年';
        ELSE
            SET age_rank := '00后';
        END IF;
        SELECT age_rank;
    END;
"""
cur.execute(sql)
cur.fetchall()
含参存储过程的执行
SET @用户变量 = '默认值';
CALL 存储过程名(输入值, @用户变量);
SELECT @用户变量;

存储过程的逻辑函数-IF

IF 条件1 THEN
  -- 满足条件1,执行此SQL
ELSEIF 条件2 THEN
  -- 满足条件2,执行此SQL
ELSE
  -- 否则执行此SQL
END IF;
  • 例:
sql = """
    CREATE PROCEDURE p4(IN age INT,OUT age_rank VARCHAR(10))
    BEGIN
        IF age >= 23 THEN
            SET age_rank := '99年';
        ELSEIF age >= 22 THEN
            SET age_rank := '00年';
        ELSE
            SET age_rank := '00后';
        END IF;
        SELECT age_rank;
    END;
"""
cur.execute(sql)
cur.fetchall()

存储过程的逻辑函数-CASE

写法一
CASE case变量
  WHEN1 THEN SQL语句1  (若case变量=1,则执行SQL语句1WHEN2 THEN SQL语句2  (若case变量=2,则执行SQL语句2ELSE SQL语句3           (否则执行SQL语句3END CASE;
写法二
CASE
  WHEN 判断语句1 THEN SQL语句1 (判断语句1为真,则执行SQL语句1WHEN 判断语句2 THEN SQL语句2 (判断语句2为真,则执行SQL语句2ELSE SQL语句3                (否则执行SQL语句2END CASE
  • 例:
sql = """
    CREATE PROCEDURE p5(IN age INT,OUT age_rank VARCHAR(10))
    BEGIN
        CASE
        WHEN age >= 23 THEN SET age_rank := '99年';
        WHEN age >= 22 THEN SET age_rank := '00年';
        ELSE SET age_rank := '00后';
        END CASE;
    END;
"""
cur.execute(sql)
cur.fetchall()

存储过程的逻辑函数-WHILE

WHILE 条件 DO
  SQL逻辑...
END WHILE;
  • 例:
sql = """
    CREATE PROCEDURE pwhile(IN n INT,INOUT result INT)
    BEGIN
        DECLARE i INT DEFAULT 0;
        WHILE i <= n DO
            SET result := result + 2;
            SET i := i + 1;
        END WHILE;
        SELECT result;
    END;
"""
cur.execute(sql)
cur.fetchall()

存储过程的逻辑函数-REPEAT

REPEAT
  SQL逻辑...
  UNTIL 条件 (满足则退出)
END REPEAT;
  • 例:
sql = """
    CREATE PROCEDURE prepeat(IN n INT,INOUT result INT)
    BEGIN
        DECLARE i INT DEFAULT 0;
        REPEAT
            SET result := result + 2;
            SET i := i + 1;
            UNTIL i > n
        END REPEAT;
        SELECT result;
    END;
"""
cur.execute(sql)
cur.fetchall()

存储过程的逻辑函数-LOOP

循环体
[标记:]LOOP  (标记用于标识loop循环)
  SQL逻辑...
END LOOP [标记];
循环逻辑
LEAVE 标记;    退出指定标记的循环体
ITERATE 标记;  直接进入下一次循环
  • 例:
sql = """
    CREATE PROCEDURE ploop(IN n INT,INOUT result INT)
    BEGIN
        DECLARE i INT DEFAULT 0;
        sum:LOOP
            IF i > n THEN
                LEAVE sum;
            END IF;
            SET result := result + 2;
            SET i := i + 1;
        END LOOP sum;
        SELECT result;
    END;
"""
cur.execute(sql)
cur.fetchall()

游标

介绍

  • 游标是用来存储查询结果集的数据类型
  • 在存储过程和函数中可以使用游标对结果集进行循环的处理
  • 用法在“条件存储程序”的例子中

声明游标

DECLARE 游标名称 CURSOR FOR 查询语句; (查询语句的结果集存储在游标中)

打开游标

OPEN 游标名称;

获取游标记录

FETCH 游标名称 INTO 变量[,变量];

关闭游标

CLOSE 游标名称;

条件存储程序

  • 用来定义再流程控制结构执行过程中遇到问题时相应的处理步骤(异常处理)
定义条件处理程序

程序主体是SQL语句,SQL语句前的关键字指定异常处理类型和条件。

DECLARE handler_action HANDLER FOR condition_value SQL语句;
handler_action (条件处理程序的类型)
条件处理程序类型的关键字作用
CONTINUE:继续执行当前程序
EXIT:终止执行当前程序
condition_value (条件):
条件的关键字作用
SQLSTATE sqlstate_value(状态码,如02000)指定状态码
SQLWARNING所有以01开头的SQLSTATE状态码
NOT FOUND所有以02开头的SQLSTATE状态码
SQLEXCEPTION所有其他开头的SQLSTATE状态码
  • 例:查找user表中年龄小于uage的记录,复制到user_pro表中。
sql = """
    CREATE PROCEDURE p11(IN uage INT)
    BEGIN
    
        DECLARE uname VARCHAR(100);
        DECLARE u_cursor CURSOR FOR SELECT name,age FROM user WHERE age <= uage;
        DECLARE EXIT HANDLER FOR SQLSTATE '02000' CLOSE u_cursor;
        
        DROP TABLE IF EXISTS user_pro;
        CREATE TABLE IF NOT EXISTS user_pro(
            id INT PRIMARY KEY AUTO_INCREMENT,
            name VARCHAR(100),
            age INT
        );
        
        OPEN u_cursor;
        WHILE TRUE DO
            FETCH u_cursor INTO uname,uage;
            INSERT INTO user_pro VALUES (NULL,uname,uage);
        END WHILE;
        CLOSE u_cursor;
        
    END;
"""
cur.execute(sql)
cur.fetchall()

存储函数

介绍

  • 是有返回值的存储过程
  • 存储函数的参数只能是IN类型

创建存储函数

CREATE FUNCTION 存储函数名称([参数列表])
  RETURNS 返回值类型 [characteristic...]
    BEGIN
      --SQL语句
      RETURN...;
    END;
characteristic(特性)
条件的关键字作用
DETERMINISTIC相同的输入参数总是产生相同的结果
NO SQL不包含SQL语句
READS SQL DATA包含读取数据的语句,但不包含写入数据的语句
  • 例:求n个2的和
sql = """
    CREATE FUNCTION floop(n INT)
    RETURNS INT DETERMINISTIC
    BEGIN
        DECLARE i INT DEFAULT 0;
        DECLARE result INT DEFAULT 0;
        sum:LOOP
            IF i > n THEN
                LEAVE sum;
            END IF;
            SET result := result + 2;
            SET i := i + 1;
        END LOOP sum;
        RETURN result;
    END;
"""
cur.execute(sql)
cur.fetchall()

执行存储函数

SELECT 存储函数名();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值