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
  • 相关阅读:
    Database Corruption ->> Fix Database In Suspect State
    Index & Statistics ->> Rebuild Index会不会覆盖原先Index的WITH选项设置
    Data Flow ->> CDC Control Task, CDC Source, CDC Splitter
    CDC ->> 在某个SQL Server中开启CDC功能
    使用OPENROWSET(BULK...)从平面文件加载数据
    Data Flow ->> DQS Cleansing
    db2look和db2move详解
    查询数据库记录数最快方法
    linux系统ftp命令
    Linux上如何查看物理CPU个数,核数,线程数
  • 原文地址:https://www.cnblogs.com/liuguniang/p/7044338.html
Copyright © 2011-2022 走看看