mysql的内置功能(视图,触发器,事物,存储过程,函数,流程控制)

 

一 视图

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

     使用视图我们可以把查询过程中的临时表摘出来,用视图去实现,这样以后再想操作该临时表的数据时就无需重写复杂的sql了,直接去视图中查找即可,但视图有明显地效率问题(不如子查询的效率高),并且视图是存放在数据库中的,如果我们程序中使用的sql过分依赖数据库中的视图,即强耦合,那就意味着扩展sql极为不便(修改视图部分要去数据库修改),因此并不推荐使用。

      1 创建视图:

#语法:CREATE VIEW 视图名称 AS  SQL语句
create view teacher_view as select tid from teacher where tname='李平老师';

     Note:修改视图,原表也会随之改变。

               但是我们不应该修改视图中的记录,而且在涉及多个表的情况下是根本无法修改视图中的记录的。

2 修改视图

语法:ALTER VIEW 视图名称 AS SQL语句
mysql> alter view teacher_view as select * from course where cid>3;

3 删除视图

语法:DROP VIEW 视图名称

DROP VIEW teacher_view
 

二 触发器

1 创建触发器

create trigger 触发器名 before/after insert on 表名 for each row

begin

...

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 row
begin
    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
    ('egon','0755','ls -l /etc',NOW(),'yes'),
    ('egon','0755','cat /etc/passwd',NOW(),'no'),
    ('egon','0755','useradd xxx',NOW(),'no'),
    ('egon','0755','ps aux',NOW(),'yes');


#查询错误日志,发现有两条
mysql> select * from errlog;
+----+-----------------+---------------------+
| id | err_cmd         | err_time            |
+----+-----------------+---------------------+
|  1 | cat /etc/passwd | 2017-09-14 22:18:48 |
|  2 | useradd xxx     | 2017-09-14 22:18:48 |
+----+-----------------+---------------------+
rows in set (0.00 sec)

Note: 触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的。

2 删除触发器

drop trigger 触发器名;
 

三 事务

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

# 创建事务

start transaction;   # 开始事务

update user set balance=900 where name='wsb'; #买支付100元
update user set balance=1010 where name='egon'; #中介拿走10元
uppdate user set balance=1090 where name='ysb'; #卖家拿到90元,出现异常没有拿到
rollback;  # 事务中有一个失败返回初始状态
commit;  # 事务结束

 

四 存储过程

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

    使用存储过程的优点:

       #1. 用于替代程序写的SQL语句,实现程序与sql解耦

      #2. 基于网络传输,传别名的数据量小,而直接传sql数据量大

   使用存储过程的缺点:  

       扩展时不方便。

1 创建存储过程 (无参)

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())


2 创建存储过程(有参)

对于存储过程,可以接收参数,其参数有三类:

#in          仅用于传入参数用
#out        仅用于返回值用
#inout     既可以传入又可以当作返回值

# in来传入参数

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())
 

# out传出返回值

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=0
print(cursor.fetchall()) #查询select的查询结果

cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一个参数,@p3_1代表第二个参数,即返回值
print(cursor.fetchall())

# inout 传入传出

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())

3 删除存储过程

     drop procedure 存储过程名

Note:

程序与数据库结合使用的三种方式

#方式一:(执行效率高,可扩展性差)
    MySQL:存储过程
    程序:调用存储过程

#方式二:(可扩展性好,效率低,编写复杂)
    MySQL:
    程序:纯SQL语句

# 方式三:(可扩展性好,编写相对简单,效率最低)

     MySQL:

     程序:类和对象,用orm来实现(本质仍是sql语句)


五 流程控制

# if语句(if   then  elseif   else   end if)

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 ;

# while循环(while 条件  do 循环体  end while)

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 ;

#repeat循环(repeat  循环体  until条件    end  repeat)

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 ;

 #loop循环( )

delimiter //
create procedure proc_loop ()
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//

delimiter;

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值