可以为sql执行过程中发生的某种类型的错误定义特殊的处理程序,定义处理程序时,使用declare语句的语法如下:
    

declare 处理方式  handler for 错误类型 处理语句

处理方式 :处理有3个取值:continue 、exit 、undo

continue :表示遇到错误不处理,继续执行

exit:表示遇到错误马上退出。

undo:表示遇到错误后撤回之前的操作,mysql中暂时不支持这样的操作

错误类型(即条件)可以有如下取值

sqlstate (SQLSTATE)‘字符串错误码’:表示长度为5的sqlstate_value 类型的错误代码;
MySQL_error_code:匹配数值类型错误代码;
错误名称:表示DECLARE... CONDITION定义的错误条件名称。
SLQWARNIG:匹配所有以01开头的SQLSTATE错误代码
NOT FOUND:匹配所有以02开头的SQLSTATE错误代码
SQLEXCEPTION:匹配所有没有被SQLWARNING或NOT FOUND捕获的SQKSTATE错误代码;

 

CREATE TABLE admin(
id INT PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(15) NOT NULL,
pwd VARCHAR(25) NOT NULL
);

SELECT * FROM admin;

DESC admin;

delimiter $
CREATE PROCEDURE insert_user(IN user VARCHAR(15),IN pwd VARCHAR(25))
BEGIN
    INSERT INTO admin(user_name,pwd)
    VALUES (user_name,pwd);
END $

delimiter $

CALL insert_user('tom','123')

CREATE TABLE beauty(
id INT PRIMARY KEY auto_increment,
`name` VARCHAR(15) NOT NULL,
phone VARCHAR(15) not NULL,
birth date
);

INSERT INTO beauty (`name`,phone,birth) VALUES 
('朱茵','123435323','1982-02-12'),
('刘诗诗','1435435323','1583-02-12'),
('邓紫棋','1238735323','1381-02-12'),
('刘亦菲','1642215323','2132-02-12');

SELECT * FROM beauty

delimiter $
CREATE PROCEDURE get_phone(IN id INT,OUT `name` VARCHAR(15),OUT phone VARCHAR(25))
BEGIN
    SELECT b.`name` ,b.phone INTO `name`,phone
    FROM beauty b
    WHERE b.id = id;
END$

delimiter ;

CALL get_phone(2,@name,@phone);
SELECT @name,@phone; 




SET @name = 

#用户变量  局部变量

#会话用户变量,使用@开头,作用域当前会话

#局部变量:只能使用在存储过程和存储函数中的


CREATE PROCEDURE test_var1()
BEGIN
    DECLARE a INT DEFAULT 0;
    DECLARE b INT DEFAULT 0;
    DECLARE `empname` VARCHAR(500);
    #赋值
    SET a = 1;
    SET b := 2;
    
    SELECT `name` INTO `empname` FROM t_base WHERE id = 1; 
    
    #使用
    SELECT a,b,`empname`;
END

DROP PROCEDURE test_var1
    
CALL test_var1()


CREATE PROCEDURE test_pro()
BEGIN 
            DECLARE emp_name VARCHAR(25);
            DECLARE sal DOUBLE(10,2) DEFAULT 0.0;
            #赋值
            SELECT `des`,id INTO emp_name,sal FROM t_base WHERE id = 1;
            #使用
            SELECT emp_name,sal;
END 

CALL test_pro()


CREATE PROCEDURE updateDataNoCondition()
    BEGIN
        #声明处理程序
        #处理方式一
            DECLARE CONTINUE HANDLER FOR 1048 SET @prc_value = -1;
        #处理方式二
            #DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @prc_value = -1;
        SET @x =1;
        写一个更新语句
        SET @x =2;
        写一个更新语句二
        SET @x =3;
        写一个更新语句三
    END;
        
        然后再调用存储过程
        
        查看变量,
    

#流程控制

CREATE PROCEDURE test_if()
BEGIN
    DECLARE last_name VARCHAR(10);
    if last_name is null 
        then SELECT 'last_name_is null';
    end if;
END;

CALL test_if



delimiter $
CREATE PROCEDURE test()
    BEGIN
        #声明变量
        DECLARE emp_sal DOUBLE; #记录员工工资
        DECLARE bounds DOUBLE; #记录奖金率
        
        #赋值
        SELECT salary INTO emp_sal FROM employees WHERE employee_id = emp_id;
        SELECT commission_pct INTO bounds from     employees WHERE employee_id = emp_id;
        
        #判断
        IF emp_sal <9000 
            THEN UPDATE emplpoyee SET salary = 9000 WHERE employee_id = emp_id;
        ELSEIF emp_sal<10000 AND bounds IS NULL
            ELSE UPDATE employees SET commssoion_pct = 0.01 WHERE employee_id = emp_id;
        ELSE     
            UPDATE employees SET salary = salary+100 WHERE employee_id = emp_id;
        END IF;
        
    END $

delimiter ;


#循环结构之loop
delimiter $
CREATE PROCEDURE test_loop()
BEGIN 
    DECLARE num INT DEFAULT 1;
    
    loop_lable:LOOP
        #重新赋值
        SET num = num + 1;
        IF num >= 10 THEN LEAVE loop_lable;
        END IF;
        
    END LOOP loop_lable;
    
    #查看num
    SELECT num;
    
END $
delimiter ;

CALL test_loop()


delimiter $
CREATE PROCEDURE update_salary_loop(OUT num INT)
BEGIN 
        #声明变量
        DECLARE avg_sal DOUBLE; #记录员工的平均工资
        
        DECLARE loop_count INT DEFAULT 0; #记录循环的次数
        
        #获取员工的平均工资
        SELECT AVG(salary) INTO avg_sal FROM employee;
        
        loop_lab:LOOP
            #结束循环的条件
            IF avg_sal >= 1200
                THEN LEAVE loop_lab;
            END IF;
            
            #如果低于12000,循环更新员工工资
            UPDATE employee SET salary = salary * 1.1;
            
            #更新avg_sal变量的值
            UPDATE AVG(salary) INTO avg_sal FROM employee;
            
            #记录循环次数
            SET loop_count = loop_count +1;
            
            END LOOP lopp_lab;

            SET num = loop_count;
END $

delimiter ;

#初始化条件
#循环条件
#循环体
#迭代条件

delimiter $
CREATE PROCEDURE test_while()
BEGIN
  #初始化条件
  DECLARE num INT DEFAULT 1;
  #循环条件
  WHILE num <= 10 DO
  #循环体(略)

  #迭代条件
  SET num = num+1;

  END WHILE;

  SELECT num;

END $

delimiter ;

 

#调用存储过程

CALL test_while

#删除存储过程
DROP PROCEDURE test_while

delimiter $
CREATE PROCEDURE test_while(OUT num INT)
BEGIN
  #声明变量
  DECLARE avg_sal DOUBLE;
  DECLARE while_count INT DEFAULT 0;

  #赋值
  SELECT AVG(salary) INTO avg_sal FROM employees ;

  WHILE avg_sal > 5000 DO
  #循环体
  UPDATE employee SET salary = salary * 0.9 ;
  SET while_count = while_count + 1;
  #再赋值
  SELECT AVG(salary) INTO avg_sal = FROM employees;
  END WHILE;

  #给num赋值
  SET num = while_count;

END $
delimiter ;

 

 

delimiter $
CREATE PROCEDURE test_repeat()
BEGIN
  #声明变量
  DECLARE num INT DEFAULT 1;

  REPEAT
  SET num = num + 1;
  UNTIL num >= 10 #不满足继续循环,满足跳出

  END REPEAT;

  #查看
  SELECT num;
  END $

delimiter ;

#调用存储过程

CALL test_repeat

 

 

 

 

 

delimiter $
CREATE PROCEDURE update_salary_repeat(OUT num INT)
BEGIN
    #声明变量
    DECLARE agv_sal DOUBLE; #记录平均工资
    DECLARE repeat_count INT DEFAULT 1; #记录循环次数

    #赋值
    SELECT AVG(salary) INTO avg_sal FROM employees;

    REPLACE
    UPDATE employees SET salary = salary *1.15;
    SET repleat_count = repleat_count + 1 ;
    SELECT AVG(salary) INTO avg_sal FROM employees;

    UNTIL avg_sal >= 13000 #这里不加分号

END REPLACE;
END $
delimiter ;

CALL update_salary_repeat(@num)

SELECT @num;

 

 

 

 

 

 

 

delimiter $
CREATE PROCEDURE test(OUT num INT)
BEGIN
    DECLARE avg_sal DOUBLE; #记录平均工资
    DECLARE while_count DEFAULT 0; #记录循环次数;

    SELECT AVG(salary) INTO avg_sal FROM employees # 初始化条件

    while_label:WHILE TRUE DO
    #循环条件
    IF avg_sal <= 10000 THEN
    LEAVE while_label;
    END IF;

    UPDATE employees SET salary = salary * 0.9;
    SET while_count = while_count + 1;

    #迭代条件
    SELECT AVG(salary) INTO avg_sal FROM employees;

    END WHILE;
    #赋值
    SET num = while_count;

END $

delimiter ;

 

 

 

 

delimiter $
CREATE PROCEDURE test_iterate()

BEGIN
  DECLARE num INT DEFAULT 0 ;
  loop_label:LOOP
  #赋值
  SET num = num + 1;

  IF num< 10
  THEN ITERATE loop_label;
  ELSEIF num > 15
  THEN LEAVE loop_label;
  END IF;

  SELECT '文本输出' ;
  END LOOP ;

END $
delimiter ;