视图 创建视图 1 2 3 4 5 6 CREATE VIEW v1 AS (SELECT 1 AS "value");CREATE VIEW v1(value ) AS (SELECT 1 );CREATE VIEW v2 AS (SELECT value + 1 FROM v1);
查看视图 1 2 3 SHOW TABLES; SHOW FULL TABLES;
修改视图 1 2 3 4 5 CREATE VIEW v1 AS (SELECT 1 AS "value");CREATE OR REPLACE VIEW v1 AS (SELECT 2 AS "value");ALTER VIEW v1 AS (SELECT 3 AS "value");
删除视图 1 DROP VIEW IF EXISTS v1,v2;
存储过程 参数
IN:当前参数为输入参数,也就是表示入参;存储过程只是读取这个参数的值。如果没有定义参数种类, 默认就是 IN ,表示输入参数
OUT:当前参数为输出参数,也就是表示出参;执行完成之后,调用这个存储过程的客户端或者应用程序就可以读取这个参数返回的值了
INOUT:当前参数既可以为输入参数,也可以为输出参数
调用存储过程 1 2 3 4 5 6 7 8 9 10 11 CALL proc(IN_VALUE);CALL proc(@OUT_VALUE );SELECT @OUT_VALUE ;SET @INOUT_VALUE = 1 ;CALL proc(@INOUT_VALUE );SELECT @INOUT_VALUE ;
示例:创建存储过程,实现累加运算,计算 1+2+…+n 等于多少
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 DROP PROCEDURE IF EXISTS proc;DELIMITER $ CREATE PROCEDURE proc(IN n INT ,OUT m INT )BEGIN DECLARE i INT DEFAULT 1 ; DECLARE result INT DEFAULT 0 ; WHILE i <= n DO SET result = result + i; SET i = i + 1 ; END WHILE; SELECT result INTO m; END $DELIMITER ; CALL proc(100 ,@result );SELECT @result ;
函数
you might want to use the less safe log_bin_trust_function_creators variable报错时需要添加READS SQL DATA
1 2 3 4 5 6 CREATE FUNCTION 函数名(参数名 参数类型,...)RETURNS 返回值类型[characteristics ...] BEGIN 函数体 END
示例:创建函数,实现累加运算,计算 1+2+…+n 等于多少
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 DROP FUNCTION IF EXISTS func;DELIMITER $ CREATE FUNCTION func(n INT )RETURNS INT READS SQL DATABEGIN DECLARE i INT DEFAULT 1 ; DECLARE result INT DEFAULT 0 ; WHILE i <= n DO SET result = result + i; SET i = i + 1 ; END WHILE; RETURN result ; END $DELIMITER ; SELECT func(100 );
变量 系统变量 1 2 3 4 5 6 SHOW GLOBAL VARIABLES;SHOW SESSION VARIABLES;SHOW VARIABLES;
查看系统变量 1 2 3 4 5 6 7 8 SHOW GLOBAL VARIABLES LIKE '%标识符%' ;SELECT @@GLOBAL .变量名;SELECT @@SESSION .变量名;SELECT @@变量名;
修改系统变量 1 2 3 4 5 6 7 8 9 SET @@global .变量名= 变量值;SET GLOBAL 变量名= 变量值;SET @@session .变量名= 变量值;SET SESSION 变量名= 变量值;
用户变量 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 SET @num = 10 ;SELECT @num ; SELECT NOW() INTO @dt FROM DUAL;SELECT @dt ;DELIMITER / / CREATE PROCEDURE add_value()BEGIN DECLARE m INT DEFAULT 1 ; DECLARE n INT DEFAULT 3 ; DECLARE SUM INT ; SET SUM = m+ n; SELECT SUM; END / / DELIMITER ;
定义条件与处理程序 定义:定义条件 是事先定义程序执行过程中可能遇到的问题, 处理程序 定义了在遇到问题时应当采取的处理方式,并且保证存储过程或函数在遇到警告或错误时能继续执行
定义条件
MySQL_error_code和sqlstate_value 都可以表示MySQL的错误
MySQL_error_code是数值类型错误代码
sqlstate_value是长度为5的字符串类型错误代码
例如,在ERROR 1418 (HY000)中,1418是MySQL_error_code,’HY000’是sqlstate_value。
例如,在ERROR 1142(42000)中,1142是MySQL_error_code,’42000’是sqlstate_value。
1 2 3 4 5 6 7 8 DECLARE 错误名称 CONDITION FOR 错误码(或错误条件)DECLARE Field_Not_Be_NULL CONDITION FOR 1048 ;DECLARE Field_Not_Be_NULL CONDITION FOR SQLSTATE '23000' ;
处理程序
处理方式:处理方式有3个取值:CONTINUE、EXIT
CONTINUE:表示遇到错误不处理,继续执行。
EXIT :表示遇到错误马上退出。
错误类型(即条件)可以有如下取值:
SQLSTATE '字符串错误码' :表示长度为5的sqlstate_value类型的错误代码;
MySQL_error_code :匹配数值类型错误代码;
错误名称:表示DECLARE ... CONDITION定义的错误条件名称。
SQLWARNING :匹配所有以01开头的SQLSTATE错误代码;
NOT FOUND :匹配所有以02开头的SQLSTATE错误代码;
SQLEXCEPTION :匹配所有没有被SQLWARNING或NOT FOUND捕获的SQLSTATE错误代码;
处理语句:如果出现上述条件之一,则采用对应的处理方式,并执行指定的处理语句。语句可以是 像SET 变量 = 值这样的简单语句,也可以是使用BEGIN ... END 编写的复合语句。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET @info = 'NO_SUCH_TABLE' ;DECLARE CONTINUE HANDLER FOR 1146 SET @info = 'NO_SUCH_TABLE' ;DECLARE no_such_table CONDITION FOR 1146 ;DECLARE CONTINUE HANDLER FOR NO_SUCH_TABLE SET @info = 'NO_SUCH_TABLE' ;DECLARE EXIT HANDLER FOR SQLWARNING SET @info = 'ERROR' ;DECLARE EXIT HANDLER FOR NOT FOUND SET @info = 'NO_SUCH_TABLE' ;DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info = 'ERROR' ;
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DELIMITER / / CREATE PROCEDURE InsertDataWithCondition() BEGIN DECLARE duplicate_entry CONDITION FOR SQLSTATE '23000' ; DECLARE EXIT HANDLER FOR duplicate_entry SET @proc_value = -1 ; SET @x = 1 ; INSERT INTO departments(department_name) VALUES ('测试' ); SET @x = 2 ; INSERT INTO departments(department_name) VALUES ('测试' ); SET @x = 3 ; END / / DELIMITER ; mysql> CALL InsertDataWithCondition(); Query OK, 0 rows affected (0.01 sec) mysql> SELECT @x ,@proc_value ; + | @x | @proc_value | + | 2 | -1 | + 1 row in set (0.00 sec)
手动报错
1 SIGNAL SQLSTATE "HY000" SET MESSAGE_TEXT = "My Error";
流程控制 分支结构 IF 1 2 3 4 IF 表达式1 THEN 操作1 [ELSEIF 表达式2 THEN 操作2 ]…… [ELSE 操作N] END IF
CASE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CASE 表达式WHEN 值1 THEN 结果1 或语句1 (如果是语句,需要加分号)WHEN 值2 THEN 结果2 或语句2 (如果是语句,需要加分号)... ELSE 结果n或语句n(如果是语句,需要加分号)END [case ](如果是放在begin end 中需要加上case ,如果放在select 后面不需要)CASE WHEN 条件1 THEN 结果1 或语句1 (如果是语句,需要加分号)WHEN 条件2 THEN 结果2 或语句2 (如果是语句,需要加分号)... ELSE 结果n或语句n(如果是语句,需要加分号)END [case ](如果是放在begin end 中需要加上case ,如果放在select 后面不需要)
循环结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 DECLARE id INT DEFAULT 0 ;add_loop:LOOP SET id = id + 1 ; IF id >= 10 THEN LEAVE add_loop; END IF; END LOOP add_loop;DECLARE i INT DEFAULT 0 ; WHILE i < 10 DO SET i = i + 1 ; END WHILE; SELECT i;DECLARE i INT DEFAULT 0 ; REPEAT SET i = i + 1 ; UNTIL i >= 10 END REPEAT; SELECT i;
跳转语句 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 DELIMITER / / CREATE PROCEDURE leave_begin(IN num INT )begin_label: BEGIN IF num<= 0 THEN LEAVE begin_label; ELSEIF num= 1 THEN SELECT AVG (salary) FROM employees; ELSEIF num= 2 THEN SELECT MIN (salary) FROM employees; ELSE SELECT MAX (salary) FROM employees; END IF; SELECT COUNT (* ) FROM employees; END / / DELIMITER ; DELIMITER / / CREATE PROCEDURE test_iterate()BEGIN DECLARE num INT DEFAULT 0 ; my_loop:LOOP SET num = num + 1 ; IF num < 10 THEN ITERATE my_loop; ELSEIF num > 15 THEN LEAVE my_loop; END IF; SELECT '尚硅谷:让天下没有难学的技术' ; END LOOP my_loop; END / / DELIMITER ;
游标 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 DECLARE cursor_name CURSOR FOR select_statement;DECLARE cur_emp CURSOR FOR SELECT employee_id,salary FROM employees;OPEN cursor_name;FETCH cursor_name INTO var_name [, var_name] ...FETCH cur_emp INTO emp_id, emp_sal ;CLOSE cursor_nameDECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1 ;
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DELIMITER $$ CREATE PROCEDURE build_email_list (INOUT email_list VARCHAR (4000 ))BEGIN DECLARE v_finished INT DEFAULT 0 ; DECLARE v_email VARCHAR (100 ) DEFAULT ""; DECLARE email_cursor CURSOR FOR SELECT email FROM employees; DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1 ; OPEN email_cursor; get_email :LOOP FETCH email_cursor INTO v_email; IF v_finished = 1 THEN LEAVE get_email; END IF; SET email_list = CONCAT( v_email, ";", email_list ); END LOOP get_email; CLOSE email_cursor; END $$DELIMITER ;
触发器 1 2 3 4 CREATE TRIGGER 触发器名称{BEFORE| AFTER} {INSERT | UPDATE | DELETE } ON 表名 FOR EACH ROW 触发器执行的语句块;
示例:数据变更日志触发器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 CREATE TABLE test( id INT ); CREATE TABLE test_log( new_id INT , old_id INT , dt DATETIME, type VARCHAR (255 ) ); DELIMITER $ CREATE TRIGGER trig_insert BEFORE INSERT ON test FOR EACH ROW BEGIN INSERT INTO test_log(new_id,dt,type) VALUES (NEW.id,NOW(),"INSERT"); END $DELIMITER; DELIMITER $ CREATE TRIGGER trig_update BEFORE UPDATE ON test FOR EACH ROW BEGIN INSERT INTO test_log(new_id,old_id,dt,type) VALUES (NEW.id,OLD.id,NOW(),"UPDATE"); END $DELIMITER; DELIMITER $ CREATE TRIGGER trig_delete BEFORE DELETE ON test FOR EACH ROW BEGIN INSERT INTO test_log(old_id,dt,type) VALUES (OLD.id,NOW(),"DELETE"); END $DELIMITER;
示例:创建多个触发器
FOLLOWS 选项允许在现有触发器之后激活新触发器
PRECEDES 选项允许在现有触发器之前激活新触发器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 DELIMITER $$ CREATE TRIGGER before_products_update BEFORE UPDATE ON products FOR EACH ROW BEGIN INSERT INTO price_logs ( product_code, price ) VALUES (old.productCode, old.msrp); END $$DELIMITER ; DELIMITER $$ CREATE TRIGGER before_products_update_2 BEFORE UPDATE ON products FOR EACH ROW FOLLOWS before_products_update BEGIN INSERT INTO user_change_logs ( product_code, updated_by ) VALUES (old.productCode, USER ()); END $$DELIMITER ;
查看/删除触发器 1 2 3 4 5 6 7 8 9 10 11 SHOW TRIGGERS FROM 数据库;SHOW CREATE TRIGGER 触发器名称SELECT * FROM information_schema.TRIGGERS WHERE trigger_schema = 'database_name' AND trigger_name = 'trigger_name' ; DROP TRIGGER IF EXISTS 数据表.触发器名称