zoukankan      html  css  js  c++  java
  • mysql数据库的基本操作(事务、变量、触发器、函数、存储过程)

    录:
    1.事务
    2.事务原理
    3.事务--回滚点    
    4.自动事务
    5.事务特性ACID
    6.变量
    7.触发器
    8.创建触发器
    9.查看触发器
    10.使用触发器
    11.触发器记录
    12.if分支
    13.while循环
    14.函数
    15.自定义函数
    16.查看函数
    17.删除函数
    18.函数的参数
    19.函数--作用域    
    20.存储过程    
    21.存储过程--参数
        
    1.事务transaction    <--返回目录
        * 需求:有一张银行账户表,有A用户给B用户转账:A账户先减少,B账户增加,但是A操作完
            之后断电了。
        * 解决方案:A减少钱,但是不要立即修改数据表,B收到钱之后,同时修改数据表。
        
        * 事务安全
            - 事务:一系列连续的操作。这些操作要么全部成功,要么全部失败。
            - 事务安全:一种保护连续操作同时满足的机制
            - 事务安全的意义:保证数据操作的完整性
            
        * 注意:引擎myisam不支持事务,也不支外键;innodb支持事务,也支持外键。
            -- 创建表时指定引擎
            drop table if exists tb_account;
            create table tb_account(
                number varchar(20) not null unique comment '账户',
                name varchar(20) not null comment '户主名',
                money decimal(10,2) default 0.0 comment '账户余额'
            )charset utf8 engine innodb;    
            insert into tb_account values(null,'0001','张三',1000.00),(null,'0002','李四',1000.00);    
        * 手动开启事务:start transaction;        
            update tb_account set money = money -100 where id = 1;
            update tb_account set money = money +100 where id = 2;
            
        * 提交事务 commit;
            
        * 回滚事务 rollback;    
            
    2.事务原理    <--返回目录
        * 事务操作原理:事务开启之后,所有的操作都会临时保存到事务日志,事务日志只有在得到commit命令
            才会同步到数据表,其他任何情况都会清空(rollback,断电,断开连接)
            
    3.事务--回滚点        <--返回目录
        * 设置回滚点:savepoint 回滚点名;
        * 回到回滚点:rollback to 回滚点名;
            
    4.自动事务    <--返回目录
        * 在mysql中,默认的都是自动事务处理,用户操作完会立即同步到数据表中
        * 自动事务,系统通过autocommit变量控制
            show variables like 'autocommit';      select @@autocommit;
        * 关闭自动事务处理 set autocommit = off/0;      
        * 自动事务处理关闭后需要手动提交或回滚
        * 通常,我们都会使用自动事务,  开启 set autocommit = on/1;
            
    5.事务特性ACID    <--返回目录
        * atomic[əˈtɒmɪk]:原子性,事务的整个操作是一个整体,不可分割,要么全部成功,要么全部失败
        * consistency[kənˈsɪstənsi]:一致性,事务操作的前后,数据表的数据没有变化
        * isolation:隔离性,事务操作时相互隔离,不受影响    
        * durability:持久性,数据一旦提交,不可改变,永久的改变数据表数据

        * 锁机制:innodb默认是行锁,但是如果在事务操作过程中,没有使用到索引,那么系统会自动全表检索数据,
            自动升级为表锁
            
    6.变量    <--返回目录
        * 系统变量:系统定义好的变量,用来控制服务器的表现的,如autocommit等
        * show variables; -- 查看所有变量     variable[ˈveriəbl]
        * 查看mysql的版本:select @@version;    show  variables like 'version';    
        * 修改系统变量:会话级别和全局级别
            会话级别 set [@@]变量名 = 修改的值;比如:set autocommit = off/0;
            全局级别 set global 变量名 = 值;
        
        * 自定义变量  set @自定义变量=值;
            select @自定义变量;    
        
        * 在mysql中,"="会默认的当成比较符号处理,mysql重写定义了赋值":="
            - set @age := 20;
        
        * mysql允许从数据表中获取数据,然后赋值给变量
            方法1:边赋值,边查看结果
                select @变量名 := 字段名 from 表名; -- 最后一个字段值赋值给变量
            方法2:只有赋值,不看结果;数据记录最多只允许获取一条,mysql不支持数组
                select 字段列表 from 表名 where id = 1 into @变量名1,@变量名2; -- 通过where条件限定只获取一条记录
            
        * 所有自定义变量都是会话级别:当前客户端当次连接有效。
            - 变量与当前用户关联,与数据库无关
        
    7.触发器    <--返回目录
        * 需求:有两张表,一张订单表,一张商品表,每生成一个订单,意味着商品的库存要减少
        * 触发器:trigger[ˈtrɪgə(r)] ,事先为某张表绑定一段代码,当表中的某些内容发生改变的时候(增删改)
            系统自动触发代码执行
            
        * 触发器:事件类型,触发时间,触发对象
            事件类型:增删改 insert delete update
            触发时间:前后,before after
            触发对象:表中的每一条记录
            
        * 一张表中只能拥有一种触发时间的一种类型的触发器:一张表最多有6个触发器(增删改*前后)
        
    8.创建触发器    <--返回目录
        * 在mysql高级结构中,没有大括号,都是用对应的字符符号代替
        * 临时修改语句结束符 delimiter 自定义符号
        * 将临时修改修正过来 delimiter ;
        * 触发器基本语法:
            create trigger 触发器名 触发时间 触发类型 on 表名 for each row
            begin    -- 代表(
            
            end      -- 代码)
        
        * 例子:
        -- 创建表 tb_goods
        create table tb_goods(
            id int primary key auto_increment,
            name varchar(20) not null,
            price decimal(10,2) default 1,
            inv int comment '库存数量'
        )charset utf8 engine innodb;
        insert into tb_goods values(null,'iphone6s',5288,100),(null,'iphone8',6288,100),(null,'iphone10',7288,100);
        
        -- 创建表 tb_order
        create table tb_order(
            id int primary key auto_increment,
            good_id int not null comment '商品id',
            g_number int comment '商品数量'
        )charset utf8 engine innodb;
        =======================创建触发器 start ===========================
        -- 临时修改语句结束符
        delimiter $$
        
        -- 触发器,订单生成一个,商品库存减少
        create trigger after_order after insert on tb_order for each row
        begin
            update tb_goods set inv = inv -1 where id = 2;
            -- select count(*) from tb_order;  -- 出错,不允许返回一个结果
        end
        $$  -- 结束符号
        
        -- 将临时修改修正过来
        delimiter ;
        =======================创建触发器 end ===========================
        * 注意:delimiter前面不能有空格等空白。所有复制以上代码到sqlyog时去掉delimiter前面的空白
        
    9.查看触发器    <--返回目录
        show triggers [like];
        show create trigger 触发器名;

    10.使用触发器    <--返回目录
        * 不需要手动调用,而是当某种情况发生时自动触发(上面的例子:当订单表插入记录自动触发)

        * 触发器删除
            触发器不能修改,只能先删除后更新
            drop trigger 触发器名;

    11.触发器记录    <--返回目录
        * 触发器记录:不管触发器是否触发了,只要当某种操作准备执行,系统就会将当前要操作的
            记录的当前状态和即将执行之后新的状态分别保留下来,供触发器使用;其中要操作的当前状态
            保存到old中,操作之后的可能形态保存到new
        * old代表的是旧记录,new代表的是新记录
            - 删除的时候是没有new的,插入的时候是没有old
            - 使用方式:old.字段名/new.字段名

        * update tb_goods set inv = inv - new.g_number where id = new.good_id;

    12.if分支    <--返回目录
        * 需求:判断商品库存是否足够;如果订单的数量大于库存,insert失败
        delimiter %%
        create trigger before_order before insert on tb_order for each row
        begin
            -- 判断商品库存是否足够
            -- 获取商品库存:商品库存在表中
            select inv from tb_goods where id = new.good_id into @inv;
            -- 比较库存
            if @inv < new.g_number then
                -- 库存不够:触发器没有提供能够阻止事件发生的能力,只能暴力终止
                insert into XXX values(XXX);
            end if
        end
        %%
        delimiter ;
        
    13.while循环    <--返回目录
        * 语法
            循环名:while 条件判断 do
                -- 执行代码
                -- 变更循环条件
                -- 循环控制leave/iterate 循环名;
            end while;
        
        * 循环控制
            mysql中没有对应的continue和break;
            iterate:迭代,类似continue,后面的代码不执行,循环重新
            leave:类似break
        
    14.函数    <--返回目录
        * 函数:将一段代码块封装到一个结构中,在需要执行代码块的时候,调用结构执行即可(代码复用)
        * 函数分为:系统函数、自定义函数
        
        * 系统函数:系统定义好的函数,直接调用即可。任何函数都有返回值,因此函数的调用是通过select调用
        
        * 字符串相关
            - substring函数:
                set @cn = '世界你好';
                select substring(@cn,1,2);  -- 结果是输出'世界'
                -- 字符串下标从1开始;substring函数操作单位是字符
            - char_length:字符长度
            - length:字节长度
                - select char_lenght(@cn),length(@cn);
            - instr:判断字符串是否在某个具体的字符串存在,存在返回位置,不存在返回0
                select instr(@cn,'你好'); -- 3
            - lpad(str,len,str2):左填充,将字符串str2填充到str左边,填充后总共len位字符
                select lpad(@cn,8,'欢迎');  -- 欢迎欢迎世界你好
                select lpad(@cn,7,'欢迎'); -- 欢迎欢世界你好
            - insert:替换
                select insert(@cn,3,1,'您');-- 从下标3开始,长度1,替换成'您';结果:世界您好
            - strcmp:字符串比较 相等返回0,小返回-1,大返回1;看校对集,默认是不区分大小写
                select strcmp(@str1,@str2);
            - upper(字符串):将字符串全部变成大写
            - lower(字符串):将字符串全部变成小写
            
        * 日期时间相关:
            select now(); -- 2018-10-07 01:30:54
            select curdate(); -- 2018-10-07
            select curtime(); -- 01:29:10
            select month(curdate()); -- 返回当前日期的月份,1~12
            select curdate(),curtime(),month(birthday字段) from tb_stu;
            
        * 数学函数
            set @x=9;
            abs(@x) 求绝对值
            sqrt(@x)求平方根
            mod(@x,@y)取模,求余

        * 加密函数
            password(str)
            md5(str)
            encode(需要加密的字符串, 密钥字符串):加密,结果是二进制,需要blob类型存储
            decode(需要加密的字符串, 密钥字符串):解密
            
    15.自定义函数    <--返回目录
        * 创建函数
            DELIMITER $$
            create function 函数名([形参列表]) returns 数据类型
            begin
                -- 函数体
                -- 返回值 return 类型;
            end
            $$
            DELIMITER ;
        
        * 例子:
            create function display() returns int
                return 100;
                
            - 自定义函数的调用    select display();
            
        * 例子:
            delimiter $$
            create function fun_book (bookId int) returns varchar(20)
            begin
                return (select bookName from tb_book where bookTypeId=bookId);
            end
            $$
            delimiter ;
            
            -- 调用存储过程
            select fun_book(1);
            
    16.查看函数    <--返回目录
        * show function status[like '模糊匹配'] [G];
        * 函数属于指定数据库,说明要在对应数据库下才可以调用。
        * 查看函数的创建语句
            show create function 函数名;
        
    17.删除函数    <--返回目录
        * drop function 函数名;
        
    18.函数的参数    <--返回目录
        * 函数定义时的参数是形参,调用时的参数是实参
        * 需求:计算1-指定数之间的和
            delimiter $$
            create function display1(int_1 int) returns int
            begin
                set @i = 1;  -- 定义回话级别的全局变量
                set @res = 0;   -- 定义回话级别的全局变量
                while @i <= int_i do
                    set @res = @res + @i;
                    set @i = @i +1;
                end while;
                return @res;
            end
            $$
            delimiter ;
            -- 函数调用
            select display(10);  select @res,@i;
            
        * 在函数内部@定义的变量在函数外部也可以访问

    19.函数--作用域    <--返回目录
        * mysql中的作用域与js中的作用域完全一样
            - 全局变量可以在任何地方使用;局部变量只能在函数内部使用;
        * 全局变量:set @变量名;定义的为全局变量
        * 局部变量:使用declare [dɪˈkleə(r)]声明,并且必须在函数体开始之前定义;
        
            delimiter $$
            create function display2(int_1 int) returns int
            begin
                declare i int default 1;    -- 定义局部变量i
                declare res int default 0;  -- 定义局部变量res
                while i <= int_i do
                    set res = res + i;
                    set i = i +1;
                end while;
                return res;
            end
            $$
            delimiter ;
        
    20.存储过程    <--返回目录
        * 存储过程简称过程procedure,是一种用来处理数据的方式。
            存储过程是一种没有返回值的函数
            
        * 创建过程
            create procedure 过程名字([形参列表])
            begin
                过程体;
            end;
            
        * 查看过程与查看函数方法一样
        
        * 调用过程  call 过程名();
        
        * 删除过程 drop procedure 过程名;
        
        * 例子:
            delimiter $$
            create procedure pro_book (in bt int, out count_num int)
            reads sql data
            begin
                select count(*) from tb_book where bookTypeId=bt;
            end
            $$
            delimiter ;
            
            -- 调用存储过程
            call pro_book(1,@total);
        
    21.存储过程--参数    <--返回目录
        * 函数的参数需要指定数据类型,过程比函数更严格
        * 过程有自己的类型限定:三种类型
            in:数据只是从外部传入到内部使用(值传递),可以是数值也可以是变量
            out:
            inout:
        MySQL的参数模式可以被定义为IN、OUT和INOUT。
      IN:这是缺省模式,它说明参数可以被传入存储程序内部,但是任何对于该参数的修改都不会被返回给调用它的程序。
      OUT:这个模式意味着存储程序可以对参数复制(修改参数的值),并且这个被修改的值会被返回给它的调用程序。
      INOUT:这个模式意味着程序既可以读取传入的参数,而且任何对于该参数的修改对于它的调用程序而言都是可见的。   
    ---

  • 相关阅读:
    等额本息计算公式推导
    使用Charles抓取APP之HTTPS请求
    服务端如何安全获取客户端请求IP地址
    HTTPS到底是个什么鬼?
    了解数字证书、数字签名与常见的加密算法
    centos下如何使用sendmail发送邮件
    Android Studio快捷键——编辑篇
    Universal-Image-Loader源码分析(二)——载入图片的过程分析
    Universal-Image-Loader源码分析(一)——ImageLoaderConfiguration分析
    Volley源码分析(五)Volley源码总结篇
  • 原文地址:https://www.cnblogs.com/xy-ouyang/p/13282109.html
Copyright © 2011-2022 走看看