mysql_存储过程

本文详细介绍了MySQL存储过程的使用,包括查看存储过程信息的三种方法、变量的定义与赋值、条件处理与流程控制,以及光标的应用。通过示例展示了如何创建、处理异常、使用光标进行循环处理以及实现流程分支。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.查看存储过程信息的三个方式

(1)#查看存储过程的 状态

SHOW PROCEDURE STATUS like 'ydfbop_oper_loadincome';

(2)#查询存储过程创建信息

SHOW create PROCEDURE ydfbop_oper_loadincome;

(3)#通过 information_schema.ROUTINES查询存储过程信息

SELECT * from information_schema.ROUTINES  WHERE ROUTINE_NAME ='ydfbop_oper_loadincome';

2.变量的定义
DECLARE date_start DATE;

3.变量的赋值
直接赋值使用SET,可以赋值常量或者表达式

查询结果赋值给变量,要求返回结果必须只有一行

CREATE FUNCTION get_customer_balance(p_customer_id INT,p_effective_date datetime)
    RETURNS DECIMAL(5,2)
    DETERMINISTIC
    READS SQL DATA
BEGIN
    ...
    DECLARE v_payments DECIMAL(5,2);
    ...
    SELECT IFNULL(SUM(payment.amount),0) INTO v_payments FROM payment
    WHERE payment.payment_date <= p_effec_date
    AND payment.customer_id = p_customer_id;
    ...
RETURN v_rentfees + v_overfees - v_payments;
END;

4.定义条件和处理

DECLARE condition_name  CONDITION  FOR condition_value

condition_value: SQLSTATE[value] sqlstate_value | mysql_error_code

示例:主键重复时会退出,不再执行其他语句
CREATE PROCEDURE actor_insert()
BEGIN
    set @x=1;
    INSERT INTO actor(actor_id,first_name,last_name) values (201,'test','201');
    set @x=2;
    INSERT INTO actor(actor_id,first_name,last_name) values (1,'test','1');
    set @x=3;
END;


解决方案:
CREATE PROCEDURE actor_insert()
BEGIN
    DECLARE CONTINUE HANDLER FOR SQLSTATE '2300'
    set @x2=1;
    set @x=1;
    INSERT INTO actor(actor_id,first_name,last_name) values (201,'test','201');
    set @x=2;
    INSERT INTO actor(actor_id,first_name,last_name) values (1,'test','1');
    set @x=3;
END;

如是:

DECLARE CONTINUE HANDLER FOR SQLSTATE '2300'

改写
1.捕获mysql_error_code
DECLARE CONTINUE HANDLER FOR 1062

2.事先定义
DECLARE duplicatekey CONDITION FOR SQLSTATE '23000'
DECLARE CONTINUE HANDLER FOR duplicatekey

3.捕获 SQLEXCEPTION
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION

5.光标
作用:对结果集进行循环处理
使用:
1.声明
    DECLARE cursor_name CURSOR FOR select_statemtn
2.打开
    OPEN cursor_name
3.抓取
    FETCH cursor_name INTO var_name[,var_name]...
4.关闭
    CLOSE cursor_name

示例:
使用光标:对payment表按照行进行循环的处理,按照staff_id值的不同累加amount的值,
                判断循环结束的条件是捕获 not found 的条件,
                当fetch光标找不到下一条记录的时候,就会关闭光标,然后退出过程.
CREATE PROCEDURE payment_stat()
BEGIN
    DECLARE i_staff_id INT;
    DECLARE d_amount DECIMAL(5,2);
    DECLARE cur_payment CURSOR FOR SELECT staff_id,amount FROM payment;
    DECLARE EXIT HANDLER FOR not found CLOSE cur_payment;

    set @x1=0;
    set @x2=0;
    
    OPEN cur_payment;
    
    REPEAT
        FETCH cur_payment INTO i_staff_id, d_amount;
        IF i_staff_id=2 THEN
            set @x1=@x1+d_amount;
        ELSE
            set @x2=@x2+d_amount;
        END IF;
    UNTIL 0 END REPEAT;
    CLOSE cur_payment;
END;

6.流程控制
1.IF

if search_condition then statement_list
ELSEIF search_condition then statement_list
ELSE statement_list
end if;

2.CASE

CASE case_value
    when when_value THEN statement_list
    WHEN when_value THEN statement_list
ELSE statement_lsit
END CASE

CASE i_staff_id
WHEN 2 THEN
        set @x1=@x1+d_amount;
ELSE
        set @x2=@x2+d_amount;
END CASE;


CASE
    WHEN search_condition then statement_list
    WHEN search_condition then statement_list
ELSE statement_list
END CASE

CASE
WHEN i_staff_id=2 THEN
        set @x1=@x1+d_amount;
ELSE
        set @x2=@x2+d_amount;
END CASE;

3.LOOP
BEGIN
    LOOP
        statement_list
    END LOOP
END

4.LEAVE

示例:
CREATE PROCEDURE actor_insert()
BEGIN
    set @x=0;
    ins: loop
        set @x=@x+1;
        IF @x=100 THEN
        LEAVE ins;
    END IF;
    INSERT INTO actor(first_name,last_name) values('test','111');
    END loop ins;
END;


5.ITERATE
须用在循环中,
作用:跳到当前循环的剩下的语句,直接进入到下一轮循环.
示例:当@x变量为偶时,不再执行循环中剩下的语句,而直接进行下一轮的循环.
create PROCEDURE actor_insert()
BEGIN
    set @x=0;
    ins:loop
        set @x=@x+1;
        if @x = 10 THEN
        LEAVE ins;
        ELSEIF `MOD`(@x,2)=0 THEN
        ITERATE ins;
        END IF;
        INSERT INTO actor(actor_id,first_name,last_name) values(@x+200,'test',@x);
    END loop ins;
end;

6.REPEAT
有条件的循环控制语句,当满足条件的时候退出循环
语法:
BEGIN
    REPEAT
        statement_list
    UNTIL search_condition
    END REPEAT

示例:
REPEAT
        FETCH cur_payment INTO i_staff_id, d_amount;
        IF i_staff_id=2 THEN
            set @x1=@x1+d_amount;
        ELSE
            set @x2=@x2+d_amount;
        END IF;
    UNTIL 0 END REPEAT;

7.WHILE
作用于有条件的循环控制语句,当满足条件时,执行相关内容
BIGINT
    while search_condition DO
        statement_list
    END WHILE
END;
七.事件调度器
简单示例:首先创建了myevent调度事件,然后执行更新操作,起始执行时间为调度器创建时间,后续在起始时间的基础上每隔1小时触发一次.
create event myevent
on schedule at CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
update myschema.mytable set mycol=mycol+1;

myevent是事件名
on SCHEDULE 子句指定 事件在何时执行及执行频次
do 子句指定要执行的具体操作或事件

示例2:
每隔5秒向表test中插入一条记录
CREATE EVENT test_event_1
ON SCHEDULE EVERY 5 SECOND
DO
insert into test.test(id1,create_time) values('test',NOW());

查看调度器状态:
SHOW EVENTS \G;

查看事件调度器状态
show VARIABLES LIKE '%scheduler%';

打开事件调度器状态
SET GLOBAL event_scheduler =1;

示例3:每隔一分钟,清空一次test表:
CREATE EVENT trunc_test
ON SCHEDULE EVERY 1 MINUTE
DO TRUNCATE TABLE test;

禁用event
alter event test_event_1 DISABLE;

删除event
drop event test_event_1;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值