博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MySQL_视图/触发器/事务/存储过程/函数
阅读量:6457 次
发布时间:2019-06-23

本文共 10584 字,大约阅读时间需要 35 分钟。

视图、触发器、事务、存储过程、函数

视图

  视图是一个虚拟表(非真实存在),其本质是根据SQL语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可获取结果集,可以将该结果集当作表来使用

#创建视图#语法:CREATE VIEW 视图名称 AS  SQL语句create view teacher_view as select tid from teacher where tname='李平';#于是查询李平老师教授的课程名的sql可以改写为select cname from course where teacher_id = (select tid from teacher_view);
#创建表course的视图create view course_view as select * from course;#更新视图中的数据update course_view set cname='xxx';#往视图中插入数据,原始表的记录也跟着修改了insert into course_view values(5,'yyy',2);#我们不应该修改视图中的记录,而且在涉及多个表的情况下是根本无法修改视图中的记录的
使用视图
#修改视图#语法:ALTER VIEW 视图名称 AS SQL语句alter view teacher_view as select * from course where cid>3;
#删除视图#语法:DROP VIEW 视图名称DROP VIEW teacher_view

触发器

  使用触发器可以定制用户对表进行(增、删、改)操作时前后的行为

# 插入前CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROWBEGIN    ...END# 插入后CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROWBEGIN    ...END# 删除前CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROWBEGIN    ...END# 删除后CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROWBEGIN    ...END# 更新前CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROWBEGIN    ...END# 更新后CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROWBEGIN    ...END
创建触发器
#准备表CREATE TABLE cmd (    id INT PRIMARY KEY auto_increment,    USER CHAR (32),    priv CHAR (10),    cmd CHAR (64),    sub_time datetime, #提交时间    success enum ('yes', 'no') #0代表执行失败);CREATE TABLE errlog (    id INT PRIMARY KEY auto_increment,    err_cmd CHAR (64),    err_time datetime);#创建触发器delimiter //CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROWBEGIN    IF NEW.success = 'no' THEN #等值判断只有一个等号            INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必须加分号      END IF ; #必须加分号END//delimiter ;#往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志INSERT INTO cmd (    USER,    priv,    cmd,    sub_time,    success)VALUES    ('lary','0755','ls -l /etc',NOW(),'yes'),    ('lary','0755','cat /etc/passwd',NOW(),'no'),    ('lary','0755','useradd xxx',NOW(),'no'),    ('lary','0755','ps aux',NOW(),'yes');
插入后触发触发器
#使用触发器触发器无法由用户直接调用,而是由于对表的[增/删/改]操作被动引发的
#删除触发器drop trigger tri_after_insert_cmd;

事务

  事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据的完整性

#出现异常,回滚到初始状态start transaction;...   #SQLrollback;commit;

存储过程

  存储过程包含了一系列可执行的SQL语句,存储过程存放于Mysql中,通过调用它的名字可以执行其内部的一堆sql

delimiter //create procedure p1()BEGIN    select * from blog;    INSERT into blog(name,sub_time) values("xxx",now());END //delimiter ;#在mysql中调用call p1()#在python中基于pymysql调用cursor.callproc('p1')print(cursor.fetchall())
创建存储过程(无参)
对于存储过程,可以接收参数,其参数有三类:#in          仅用于传入参数用#out        仅用于返回值用#inout     既可以传入又可以当作返回值
delimiter //create procedure p2(    in n1 int,    in n2 int)BEGIN    select * from blog where id > n1;END //delimiter ;#在mysql中调用call p2(3,2)#在python中基于pymysql调用cursor.callproc('p2',(3,2))print(cursor.fetchall())
in
delimiter //create procedure p3(    in n1 int,    out res int)BEGIN    select * from blog where id > n1;    set res = 1;END //delimiter ;#在mysql中调用set @res=0; #0代表假(执行失败),1代表真(执行成功)call p3(3,@res);select @res;#在python中基于pymysql调用cursor.callproc('p3',(3,0)) #0相当于set @res=0print(cursor.fetchall()) #查询select的查询结果cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数,@p3_1代表第二个参数,即返回值print(cursor.fetchall())
out
delimiter //create procedure p4(    inout n1 int)BEGIN    select * from blog where id > n1;    set n1 = 1;END //delimiter ;#在mysql中调用set @x=3;call p4(@x);select @x;#在python中基于pymysql调用cursor.callproc('p4',(3,))print(cursor.fetchall()) #查询select的查询结果cursor.execute('select @_p4_0;')print(cursor.fetchall())
inout
#介绍delimiter //            create procedure p4(                out status int            )            BEGIN                1. 声明如果出现异常则执行{                    set status = 1;                    rollback;                }                开始事务                    -- 由秦兵账户减去100                    -- 方少伟账户加90                    -- 张根账户加10                    commit;                结束                set status = 2;            END //            delimiter ;#实现delimiter //create PROCEDURE p5(    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;        DELETE from tb1; #执行失败        insert into blog(name,sub_time) values('yyy',now());    COMMIT;    -- SUCCESS    set p_return_code = 0; #0代表执行成功END //delimiter ;#在mysql中调用存储过程set @res=123;call p5(@res);select @res;#在python中基于pymysql调用存储过程cursor.callproc('p5',(123,))print(cursor.fetchall()) #查询select的查询结果cursor.execute('select @_p5_0;')print(cursor.fetchall())
事务
#执行存储过程call proc_name()  #五参数call proc_name(1,2) #有参数,全inset @t1=0;set @t2=3;call proc_name(1,2,@t1,@t2)  #有参数,有in,out,inout
#!/usr/bin/env python# -*- coding:utf-8 -*-import pymysqlconn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1')cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)# 执行存储过程cursor.callproc('p1', args=(1, 22, 3, 4))# 获取执行完存储的参数cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3")result = cursor.fetchall()conn.commit()cursor.close()conn.close()print(result)
在python中执行存储过程
#删除存储过程drop procedure proc_name;

函数

一、数学函数    ROUND(x,y)        返回参数x的四舍五入的有y位小数的值    RAND()        返回0到1内的随机值,可以通过提供一个参数(种子)使RAND()随机数生成器生成一个指定的值。二、聚合函数(常用于GROUP BY从句的SELECT查询中)    AVG(col)返回指定列的平均值    COUNT(col)返回指定列中非NULL值的个数    MIN(col)返回指定列的最小值    MAX(col)返回指定列的最大值    SUM(col)返回指定列的所有值之和    GROUP_CONCAT(col) 返回由属于一组的列值连接组合而成的结果三、字符串函数    CHAR_LENGTH(str)        返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。    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)        变大写    REVERSE(str)        返回字符串 str ,顺序和字符顺序相反。    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'四、日期和时间函数    CURDATE()或CURRENT_DATE() 返回当前的日期    CURTIME()或CURRENT_TIME() 返回当前的时间    DAYOFWEEK(date)   返回date所代表的一星期中的第几天(1~7)    DAYOFMONTH(date)  返回date是一个月的第几天(1~31)    DAYOFYEAR(date)   返回date是一年的第几天(1~366)    DAYNAME(date)   返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);    FROM_UNIXTIME(ts,fmt)  根据指定的fmt格式,格式化UNIX时间戳ts    HOUR(time)   返回time的小时值(0~23)    MINUTE(time)   返回time的分钟值(0~59)    MONTH(date)   返回date的月份值(1~12)    MONTHNAME(date)   返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);    NOW()    返回当前的日期和时间    QUARTER(date)   返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);    WEEK(date)   返回日期date为一年中第几周(0~53)    YEAR(date)   返回日期date的年份(1000~9999)    重点:    DATE_FORMAT(date,format) 根据format字符串格式化date值       mysql> SELECT DATE_FORMAT('2009-10-04 22:23:00', '%W %M %Y');        -> 'Sunday October 2009'       mysql> SELECT DATE_FORMAT('2007-10-04 22:23:00', '%H:%i:%s');        -> '22:23:00'       mysql> SELECT DATE_FORMAT('1900-10-04 22:23:00',        ->                 '%D %y %a %d %m %b %j');        -> '4th 00 Thu 04 10 Oct 277'       mysql> SELECT DATE_FORMAT('1997-10-04 22:23:00',        ->                 '%H %k %I %r %T %S %w');        -> '22 22 10 10:23:00 PM 22:23:00 00 6'       mysql> SELECT DATE_FORMAT('1999-01-01', '%X %V');        -> '1998 52'       mysql> SELECT DATE_FORMAT('2006-06-00', '%d');        -> '00'五、加密函数    MD5()        计算字符串str的MD5校验和    PASSWORD(str)        返回字符串str的加密版本,这个加密过程是不可逆转的,和UNIX密码加密过程使用不同的算法。六、控制流函数    CASE WHEN[test1] THEN [result1]...ELSE [default] END        如果testN是真,则返回resultN,否则返回default    CASE [test] WHEN[val1] THEN [result]...ELSE [default]END        如果test和valN相等,则返回resultN,否则返回default    IF(test,t,f)        如果test是真,返回t;否则返回f    IFNULL(arg1,arg2)        如果arg1不是空,返回arg1,否则返回arg2    NULLIF(arg1,arg2)        如果arg1=arg2返回NULL;否则返回arg1
mysql内置函数
delimiter //create function f1(    i1 int,    i2 int)returns intBEGIN    declare num int;    set num = i1 + i2;    return(num);END //delimiter ;delimiter //create function f5(    i int)returns intbegin    declare res int default 0;    if i = 10 then        set res=100;    elseif i = 20 then        set res=200;    elseif i = 30 then        set res=300;    else        set res=400;    end if;    return res;end //delimiter ;
自定义函数
#删除函数drop function func_name;
#执行函数# 获取返回值select UPPER('egon') into @res;SELECT @res;# 在查询中使用select f1(11,nid) ,name from tb2;

流程控制

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 ;
if
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 ;
while
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 ;
repeat
BEGIN    declare i int default 0;    loop_label: loop        set i=i+1;        if i<8 then            iterate loop_label;        end if;        if i>=10 then            leave loop_label;        end if;        select i;    end loop loop_label;END
loop

  

转载于:https://www.cnblogs.com/iamluoli/p/9596939.html

你可能感兴趣的文章
P1486 [NOI2004]郁闷的出纳员
查看>>
团队贡献分配计划
查看>>
LCA 最近公共祖先
查看>>
9.8 开课第五天(标签:表单标签)(9.7休息)
查看>>
什么是层叠上下文?如何形层叠上下文?层叠顺序是怎样的?
查看>>
一个项目要被自己加载的swf的项目调用方法
查看>>
给初学者的RxJava2.0教程(四)(转)
查看>>
一个伪作家谈如何让孩子爱上写作文
查看>>
SQLServer 里面的 DDL,DML,DCL,TCL
查看>>
线程可见性与原子性
查看>>
RPM卸载软件包
查看>>
思想笔记-08
查看>>
Java面向对象----方法重载
查看>>
[2019.2.24]BZOJ2662 [BeiJing wc2012]冻结
查看>>
持续集成--01构建工具概览
查看>>
configparser的用法
查看>>
Ftp实用类
查看>>
在 Vim 中优雅地查找和替换(转)
查看>>
复习(2)
查看>>
.net List的并集和交集
查看>>