zoukankan      html  css  js  c++  java
  • mysql基础(三)之服务端的其他查询工具


    参考博客:http://www.cnblogs.com/wupeiqi/articles/5713323.html
    以下视图,触发器,函数,存储过程都是放在mysql的服务端,可以在mysql客户端或pymysql中直接调用它的名字

    视图
    为某个查询语句(临时表)设置别名,日后方便使用
    视图是一个虚拟表,其本质是根据sql语句获取动态的数据集,并为其命名,用户使用时只需使用名称即可
    不常用

    创建视图: create view t1 as sql语句
    修改 alter view t1 as sql语句
    删除 drop view t1

    使用视图: select * from t1;
    触发器
    当对某张表做:增删改操作时,可以使用触发器自定义关联行为 before after

    delimiter //
    create trigger t1 before insert on student for each row
    begin
    insert into teacher(tname) values(new.sname);
    insert into teacher(tname) values(new.sname);
    end //
    delimiter ;
    触发器无法由用户直接使用,而是由对表的操作被动引发的
    insert into student(gender,class_id,sname) values('女',1,'陈涛'),('女',1,'陈涛')
    删除触发器
    drop trigger t1;

    new : 代指新数据,进行增,改操作时用到
    old : 代指老数据,进行删除操作时用到

    函数
    内置函数:
    官网查询: https://dev.mysql.com/doc/refman/5.7/en/functions.html
    执行函数 select curdate();
    例如blog
    id title ctime
    1 asdf 2019-11-8 14:05:03
    2 asdf 2019-11-8 14:05:03
    3 asdf 2019-10-6 14:05:03
    4 asdf 2019-10-5 14:05:03

    select ctime,count(1) from blog group ctime 失败
    需要进行日期格式化:
    select date_format(ctime,'%Y-%m'),count(1) from blog group by data_format(ctime,'%Y-%m')
    结果:
    2019-11 2
    2019-10 2
    自定义函数: 有参数和返回值,函数体不能放sql语句
    delimiter //
    create function f1(
    i1 int,
    i2 int
    )
    returns int
    begin
    declare num int default 0;
    set num = i1 + i2;
    return(num);
    end //
    delimiter ;
    运行函数:select f1(1,2);


    存储过程: 有参数,无返回值,可以放sql语句
    存储过程是一个sql语句的集合,当主动去调用存储过程时,其中内部的sql语句会按照逻辑执行
    用于替代程序员写sql语句:应用的3中方式:
    方式一:
    MySQL服务端: 存储过程
    程序:调用存储过程
    方式二:
    MySQL服务端:do nothing
    程序:SQL语句
    方式三:
    MySQL服务端:do nothing
    程序:类和对象(SQL语句)
    1 简单无参:
    delimiter //
    create procedure p1()
    begin
    select * from student;
    INSERT into teacher(tname) values("ct");
    end
    delimiter ;

    调用:
    mysql客户端 : call p1()
    程序调用: cursor.callproc('p1')
    2 传参数 (in out inout) inout : 输入实参-----处理----输出参数
    delimiter //
    create procedure p3(
    in n1 int,
    inout n2 int
    )
    BEGIN
    set n2 = 123123;
    select * from student where sid > n1;
    END //
    delimiter ;

    客户端调用
    set @v1=10;
    call p3(12,@v1);
    select @v1;


    程序调用:
    cursor.callproc('p3',(12,10))
    r1=cursor.fetchall()
    print(r1)
    cursor.execute('select @_p3_0,@_p3_1')
    r2=cursor.fetchall()
    print(r2)

    3 为什么有结果集又有out伪造的返回值 : 用于标识存储过程的执行结果
    事务: out :输入形参
    事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性。
    伪代码:
    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;

    START TRANSACTION;
    DELETE from tb1;
    insert into tb2(name)values('seven');
    COMMIT;

    -- SUCCESS
    set p_return_code = 2;

    END\
    delimiter ;
    4 游标: 用于要对数据行中的每一行进行不同的操作(对数据行进行循环遍历)
    循环会降低数据库的运行效率,一般不进行循环操作,将数据行取出来之后在程序中进行处理
    delimiter //
    create procedure p6()
    begin
    declare row_id int; -- 自定义变量1
    declare row_num int; -- 自定义变量2
    declare done INT DEFAULT FALSE;
    declare temp int;

    declare my_cursor CURSOR FOR select id,num from A;
    declare CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    open my_cursor;
    xxoo: LOOP
    fetch my_cursor into row_id,row_num;
    if done then
    leave xxoo;
    END IF;
    set temp = row_id + row_num;
    insert into B(number) values(temp);
    end loop xxoo;
    close my_cursor;
    end //
    delimter ;
    6. 动态执行SQL(防SQL注入)
    伪代码:
    delimiter //
    create procedure p7(
    in tpl varchar(255),
    in arg int
    )
    begin
    1. 预检测某个东西 SQL语句合法性
    2. SQL =格式化 tpl + arg
    3. 执行SQL语句

    set @xo = arg;
    PREPARE xxx FROM 'select * from student where sid > ?';
    EXECUTE xxx USING @xo;
    DEALLOCATE prepare prod;
    end //
    delimter ;

    call p7("select * from tb where id > ?",9)
    代码:

    delimiter \
    CREATE PROCEDURE p8 (
    in nid int
    )
    BEGIN
    set @nid = nid;
    PREPARE prod FROM 'select * from student where sid > ?';
    EXECUTE prod USING @nid;
    DEALLOCATE prepare prod;
    END\
    delimiter ;

    7 循环
    条件语句:
    delimiter \
    create procedure pro_if()
    begin
    declare i int default 0;
    if i = 1 then
    select 1;
    elseif i =2 then
    select 2;
    else
    select 3;
    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 ;
    循环语句: 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:
    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
  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯VIP基础练习 矩形面积交
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
    在Linux中如何利用backtrace信息解决问题
  • 原文地址:https://www.cnblogs.com/liuguniang/p/7044338.html
Copyright © 2011-2022 走看看