总结三十五

视图

什么是视图?

  一个查询语句的结果是一张虚拟表,将这种虚拟表保存下来,它就变成了一个视图

为什么要用视图?

  当频繁需要用到多张表的连表结果,你就可以事先生成好视图

  之后直接调用即可,避免了反复写连表操作的sql语句

如何使用?

  create view teacher_course as select * from teacher INNER JOIN course

  on teacher.tid = course.teacher_id;

1.视图只有表结构,视图中的数据还是来源于原来的表

2.不要改动视图表中的数据

3.一般情况下不会频繁的使用视图来写业务逻辑

触发器

  到达某个条件自动触发

  当你在对数据进行增、删、改的情况下会自动触发触发器的运行

  

  触发器分为六种情况

    固定语法结构

      create trigger 触发器的名字 after/before insert/update/delete on 表名 for each raw

      begin

        sql语句

      end

      create trigger tri_before/after_insert/update/delete_t1 after/before insert/update/delete on t1 for each row

      begin

        sql语句

      end

      可以修改MySQL默认的结束符(;)

      delimiter $$ # 只对当前窗口有效

      create trigger tri_before_insert_user before insert on user for each row
      begin
        select * from user
      end $$
      delimiter ;

    增前

    增后

    删前

    删后

    改前

    改后

# 针对插入
create trigger tri_after_insert_t1 after insert on 表名 for each row
begin
    sql代码。。。
end 
create trigger tri_after_insert_t2 before insert on 表名 for each row
begin
    sql代码。。。
end

# 针对删除
create trigger tri_after_delete_t1 after delete on 表名 for each row
begin
    sql代码。。。
end
create trigger tri_after_delete_t2 before delete on 表名 for each row
begin
    sql代码。。。
end

# 针对修改
create trigger tri_after_update_t1 after update on 表名 for each row
begin
    sql代码。。。
end
create trigger tri_after_update_t2 before update on 表名 for each row
begin
    sql代码。。。
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 $$  # 将mysql默认的结束符由;换成$$
create trigger tri_after_insert_cmd after insert on cmd for each row
begin
    if NEW.success = 'no' then  # 新记录都会被MySQL封装成NEW对象
        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');

# 查询errlog表记录
select * from errlog;
# 删除触发器
drop trigger tri_after_insert_cmd;
案例

事物

  事物包含一大堆sql语句,这些sql要么同时成功,要么一个也别想成功

事物的作用

  保证了对数据操作的数据安全性

  案例:用交行的卡操作建行ATM机给工商的账户转钱

事物的四大特性:ACID

  A:原子性

  C:一致性

  I:隔离性

  D:持久性

原子性(atomicity):一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation):一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

如何开启事物

  start transaction

事物回滚

  rollback

永久性更改

  commit

存储过程

  类似于python中的自定义函数

  内部封装了操作数据库的sql语句,后续想要实现相应的操作,只需要调用存储过程即可

  语法结果 

    delimiter $$
    create procedure p1()
    begin
      select * from user;
    end $$
    delimiter ;

  带参数的 

    delimiter $$
    create procedure p1(
      n m int, # 不能被返回出去
      in n int,
      out res int, # 可以被返回
      inout xxx int, # 既可以进又可以出
    )
    begin
      select * from user;
    end $$
    delimiter ;

delimiter $$
create procedure p1(
    in m int,  # in表示这个参数必须只能是传入不能被返回出去
    in n int,
    out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
)
begin
    select tname from teacher where tid > m and tid < n;
    set res=0;  # 就类似于是一个标志位 用来标识存储器是否执行成功
end $$
delimiter ;

set @res = 10   # 设置一个变量与值的绑定关系

调用存储过程 将变量@res传入

之后通过
select @res
查看存储过程执行完成后的返回结果

存储过程在哪个库下面定义 就只能在哪个库下面使用


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;
      update user set balance=900 where id =1;
      update user123 set balance=1010 where id = 2;
      update user set balance=1090 where id =3;
  COMMIT;

  -- SUCCESS
  set p_return_code = 0; #0代表执行成功

END //
delimiter ;

pymysql调用存储过程

import pymysql

conn = pymysql.connect(
    host = '127.0.0.1',
    port = 3306,
    user = 'root',
    password = '123',
    database = 'day38',
    charset = 'utf8',
    autocommit = True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
# call p1()  mysql中调用
# callproc()  pymysql中调用
cursor.callproc('p1',(1,5,10))
# 内部自动用变量名存储了对应的值
print(cursor.fetchall())
"""
@_p1_0=1
@_p1_1=5
@_p1_2=10

@_存储过程名_索引值
"""

cursor.execute('select @_p1_0')
print(cursor.fetchall())
cursor.execute('select @_p1_1')
print(cursor.fetchall())
cursor.execute('select @_p1_2')
print(cursor.fetchall())

流程控制

if
# 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
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 ;

猜你喜欢

转载自www.cnblogs.com/TZZ1995/p/11400962.html
今日推荐