MySQL 视图.存储过程.触发器.函数.事务.动态执行sql
1.MySQL 视图是一张虚拟的表,是查询的结果集合。仅作查询使用
创建视图:
create view v1 as select * from coursetostudent left join course on coursetostudent.course_id = course.cid left join student on coursetostudent.student_id = student.sid
删除视图:
drop view v1;
修改视图:
alter view v1 as select course_name,student_name,age,sid from coursetostudent left join course on coursetostudent.course_id = course.cid left join student on coursetostudent.student_id = student.sid
查询视图:
select * from v1;
2.存储过程: sql语句的集合,调用存储过程,sql语句按顺序执行
创建存储过程:
delimiter $$ -- 让终端以$$作为结束符 drop procedure if exists proc_p1 $$ -- 如果存在改存储过程,则删除 create procedure proc_p1() -- 创建存储过程 begin select * from course; end $$ delimiter ; -- 恢复终端以; 作为结束符 call proc_p1(); -- 调用无参数的存储过程
带参数的存储过程:
其参数有三类:
in 仅用于传入参数用
out 仅用于返回值用
inout 既可以传入又可以当作返回值
delimiter $$ drop procedure if exists proc_p1 $$ create procedure proc_p1( in aa int, inout bb int, out cc int ) begin if aa = 1 then set bb = bb + aa; elseif aa = 2 then set bb = bb * aa; else set bb = bb + 3; end if; set cc = bb + 200; end $$ delimiter ; set @m = 2; set @n = 3; call proc_p1(3,@m,@n); select @m,@n;
3. pysql 执行存储过程
delimiter $$ drop procedure if exists proc_p1 $$ create procedure proc_p1( in aa char(10), inout bb int, out cc int ) begin declare dd int default 3; declare ee int; set ee = 5; select * from course where course.course_name = aa; set bb = bb + dd; set cc = bb * ee; end $$ delimiter ; set @m =2; set @n =3; call proc_p1('语文',@m,@n); select @m,@n;
#!/usr/bin/env python # --*-- encoding:utf-8 --*-- import pymysql # latin-1' codec can't encode character ...错误 解决方案:use_unicode=True, charset="utf8 conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='root',db='dbone', use_unicode=True, charset="utf8") cursor=conn.cursor(pymysql.cursors.DictCursor) #执行存储过程 cursor.callproc('proc_p1',args=('语文',2,3)) # 取存储过程的查询结果 result = cursor.fetchall() #执行获取存储过程的sql cursor.execute('select @_proc_p1_0, @_proc_p1_1, @_proc_p1_2') # 取存储过程的返回值 result = cursor.fetchone() conn.commit() cursor.close() conn.close()
将查出来的结果赋值给一个变量 :select into
delimiter $$ drop procedure if exists proc_p2 $$ create procedure proc_p2() begin declare mm int default 0; select course_id into mm from coursetostudent where student_id = 8; select course_name from course where cid = mm; end $$ delimiter ; call proc_p2();
4.触发器
对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为。
创建触发器:
# 插入前 CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW BEGIN ... END # 插入后 CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW BEGIN ... END # 删除前 CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW BEGIN ... END # 删除后 CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW BEGIN ... END # 更新前 CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW BEGIN ... END # 更新后 CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW BEGIN ... END
特别的:NEW表示即将插入的数据行,OLD表示即将删除的数据行。
使用:
delimiter $$ drop trigger if exists tg_before_insert_one $$ create trigger tg_before_insert_one before insert on course for each row begin update student set student_name = '张三1' where student_name = '张三'; end $$ delimiter ;
删除触发器:
drop trigger tg_before_insert_one;
使用触发器:
insert into course(course_name) values('美术')
delimiter $$ drop trigger if exists tg_before_insert_two; create trigger tg_before_insert_two before insert on course for each row begin if new.course_name = '体育' then insert into student(student_name,age) values(new.course_name,19); elseif new.course_name = '计算机' then insert into student(student_name,age) values(new.course_name,20); else insert into student(student_name,age) values(new.course_name,21); end if; end $$ delimiter ; insert into course(course_name) values('体育');
注:更新本表的触发器:不是使用update,而是set
查询触发器,储存过程,函数:
-- show triggers/g;
-- show procedure status;
-- show create procedure proc_p1;
-- show function status;
5.函数。在函数内部无法返回结果集,必须通过select func();调用。
CHAR_LENGTH(str) 返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。 对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。 CONCAT(str1,str2,...) 字符串拼接 如有任何一个参数为NULL ,则返回值为 NULL。 CONCAT_WS(separator,str1,str2,...) 字符串拼接(自定义连接符) CONCAT_WS()不会忽略任何空字符串。 (然而会忽略所有的 NULL)。 CONV(N,from_base,to_base) 进制转换 例如: SELECT CONV('a',16,2); 表示将 a 由16进制转换为2进制字符串表示 FORMAT(X,D) 将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若 D 为 0, 则返回结果不带有小数点,或不含小数部分。 例如: SELECT FORMAT(12332.1,4); 结果为: '12,332.1000' INSERT(str,pos,len,newstr) 在str的指定位置插入字符串 pos:要替换位置其实位置 len:替换的长度 newstr:新字符串 特别的: 如果pos超过原字符串长度,则返回原字符串 如果len超过原字符串长度,则由新字符串完全替换 INSTR(str,substr) 返回字符串 str 中子字符串的第一个出现位置。 LEFT(str,len) 返回字符串str 从开始的len位置的子序列字符。 LOWER(str) 变小写 UPPER(str) 变大写 LTRIM(str) 返回字符串 str ,其引导空格字符被删除。 RTRIM(str) 返回字符串 str ,结尾空格字符被删去。 SUBSTRING(str,pos,len) 获取字符串子序列 LOCATE(substr,str,pos) 获取子序列索引位置 REPEAT(str,count) 返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。 若 count <= 0,则返回一个空字符串。 若str 或 count 为 NULL,则返回 NULL 。 REPLACE(str,from_str,to_str) 返回字符串str 以及所有被字符串to_str替代的字符串from_str 。 REVERSE(str) 返回字符串 str ,顺序和字符顺序相反。 RIGHT(str,len) 从字符串str 开始,返回从后边开始len个字符组成的子序列 SPACE(N) 返回一个由N空格组成的字符串。 SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len) 不带有len 参数的格式从字符串str返回一个子字符串,起始于位置 pos。带有len参数的格式从字符串str返回一个长度同len字符相同的子字符串,起始于位置 pos。 使用 FROM的格式为标准 SQL 语法。也可能对pos使用一个负值。假若这样,则子字符串的位置起始于字符串结尾的pos 字符,而不是字符串的开头位置。在以下格式的函数中可以对pos 使用一个负值。 mysql> SELECT SUBSTRING('Quadratically',5); -> 'ratically' mysql> SELECT SUBSTRING('foobarbar' FROM 4); -> 'barbar' mysql> SELECT SUBSTRING('Quadratically',5,6); -> 'ratica' mysql> SELECT SUBSTRING('Sakila', -3); -> 'ila' mysql> SELECT SUBSTRING('Sakila', -5, 3); -> 'aki' mysql> SELECT SUBSTRING('Sakila' FROM -4 FOR 2); -> 'ki' TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str) TRIM(remstr FROM] str) 返回字符串 str , 其中所有remstr 前缀和/或后缀都已被删除。若分类符BOTH、LEADIN或TRAILING中没有一个是给定的,则假设为BOTH 。 remstr 为可选项,在未指定情况下,可删除空格。 mysql> SELECT TRIM(' bar '); -> 'bar' mysql> SELECT TRIM(LEADING 'x' FROM 'xxxbarxxx'); -> 'barxxx' mysql> SELECT TRIM(BOTH 'x' FROM 'xxxbarxxx'); -> 'bar' mysql> SELECT TRIM(TRAILING 'xyz' FROM 'barxxyz'); -> 'barx' 部分内置函数
自定义函数:
delimiter $$ drop function if exists func $$ create function func( aa int , bb int ) returns int begin declare cc int default 5; declare dd int; set cc = 6; set dd = aa + bb + cc; return(dd); end $$ delimiter ;
删除函数: drop function func;
执行函数:
# 获取返回值 declare @i VARCHAR(32); select UPPER('abcdefg') into @i; SELECT @i; # 在查询中使用 select func(11,cid),cid from course;
6.事务 :多个sql语句 作为原子性操作,只要某一个sql语句出错,则回滚到最初的状态,保证数据库的完整性
包含事务的存储过程:类似于try except
delimiter $$ drop procedure if exists p1; create PROCEDURE p1( OUT p_return_code tinyint ) BEGIN DECLARE exit handler for sqlexception BEGIN -- ERROR set p_return_code = 1; rollback; END; DECLARE exit handler for sqlwarning BEGIN -- WARNING set p_return_code = 2; rollback; END; START TRANSACTION; update user set assert = assert-10 where username = 'abc'; update user set assert = assert+10 where username = 'bcd'; COMMIT; -- SUCCESS set p_return_code = 0; END $$ delimiter ;
执行调用:
set @res = 0; call p1(@res); select @res;
7.条件,循环,动态执行SQL
delimiter $$ CREATE PROCEDURE proc_if () BEGIN declare i int default 0; if i = 1 THEN SELECT 1; ELSEIF i = 2 THEN SELECT 2; ELSE SELECT 7; END IF; END $$ delimiter ;
delimiter $$ CREATE PROCEDURE proc_while () BEGIN DECLARE num INT ; SET num = 0 ; WHILE num < 10 DO SELECT num ; SET num = num + 1 ; END WHILE ; END $$ delimiter ;
delimiter $$ CREATE PROCEDURE proc_repeat () BEGIN DECLARE i INT ; SET i = 0 ; repeat select i; set i = i + 1; until i >= 5 end repeat; END $$ delimiter ;
delimiter $$ CREATE PROCEDURE proc_loop () BEGIN declare i int default 0; loop_label: loop select i; set i=i+1; if i>=5 then leave loop_label; end if; end loop; END $$ delimiter ;
动态执行sql:也可以防止sql注入
delimiter $$ DROP PROCEDURE IF EXISTS proc_sql $$ CREATE PROCEDURE proc_sql () BEGIN declare p1 int; set p1 = 11; set @p1 = p1; PREPARE prod FROM 'select * from tb2 where nid > ?'; EXECUTE prod USING @p1; DEALLOCATE prepare prod; END $$ delimiter ;
demo:
delimiter $$ DROP PROCEDURE IF EXISTS proc_sql $$ CREATE PROCEDURE proc_sql ( in str_sql char(100), in cid int(5) ) BEGIN set @strsql = str_sql; set @cid = cid; PREPARE prod FROM @strsql; EXECUTE prod USING @cid; DEALLOCATE prepare prod; END $$ delimiter ;
import pymysql conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',passwd='root',db='dbone',use_unicode=True, charset="utf8") cursor=conn.cursor(pymysql.cursors.DictCursor) strsql = 'select * from course where cid > ?' cursor.callproc('proc_sql',(strsql,3)) result = cursor.fetchall(); print(result) conn.commit() cursor.close() conn.close()
mysql变量:
http://www.cnblogs.com/zhuawang/p/4090916.html

浙公网安备 33010602011771号