1. 程式人生 > >視圖,觸發器,事務,存儲過程,函數,流程控制,

視圖,觸發器,事務,存儲過程,函數,流程控制,

部門 ces fault PE time into 事務 sele else

一,視圖
1,什麽是視圖?
視圖就是通過查詢得到一張虛擬表,然後保存下來,下次用的話直接使用即可
2,為什麽要用視圖
如果要頻繁使用一張虛擬表,可以不用重復查詢
3,怎麽用?
在查詢前面加 create view 視圖名稱 as sql語句
create view teacher_view as select tid from teacher where tname=‘李平老師‘;
強調:在硬盤中,視圖只有表結構文件,沒有數據文件
視圖開發盡量不用 因為是在mysql裏面 ,視圖通常用於插敘,盡量不要修改視圖中的數據
2,修改視圖:alter view 視圖名稱 as sql語句
3,刪除視圖:drop view 視圖名稱


二,觸發器

1,觸發器
在滿足對某張表增刪改的情況下,自動觸發的功能稱之為觸發器 註意:沒有查詢
2,為什麽用觸發器
觸發器專門針對我們對某一張表數據增insert,刪delete,改update的行為,這類行為一旦執行
就會觸發觸發器的執行,即自動運行另外一段sql代碼

3,創建觸發器語法
create trigger tril after
針對插入
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 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 04 案例 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 ; drop trigger tri_after_insert_cmd;
觸發器的兩個關鍵字:new ,old
-- new :表示新的記錄
-- old:表示舊的那條記錄
-- 什麽情況下才往裏面插記錄
-- 當命令輸入錯誤的時候就把錯誤的記錄插入到err_log表中


三,事務(重重重)
1,什麽是事務?
開啟一個事務可以包含一些sql語句要麽同時成功,這些sql語句要麽成功
要麽一個都別想成功,稱為事務的原子性·

2,事務的作用
務用於將某些操作的多個SQL作為原子性操作,一旦有某一個出現錯誤,
即可回滾到原來的狀態,從而保證數據庫數據完整性。
事務也就是要麽都成功,要麽都不成功
事務就是由一堆sql語句組成的
3,如何用?
 create table user(
    id int primary key auto_increment,
    name char(32),
    balance int
    );
    insert into user(name,balance)
    values(wsb,1000),
    (egon,1000),
    (ysb,1000);

    try:
        update user set balance=900 where name=wsb;
        update user set balance=1010 where name=egon;
        update user set balance=1090 where name=ysb;
    except 異常:
        rollback;
    else:
        commit;
如果都成功就執行commit,,,如果不成功就執行rollback。
rollback; #如果任意一條sql出現異常,都應該回歸到初始狀態
四,存儲過程(重重重)
1,存儲過程包含了一系列可執行的sql語句,存儲過程存放於MySQL中,通過調用它的名字可以執行其內部的一堆sql
存儲過程的優點:
    1.程序與數據實現解耦
     2.減少網絡傳輸的數據量
但是看似很完美,還是不推薦你使用
Mysql當中的函數不能單獨調用

表豎著顯示\G
2, 三種開發模型
    1、
        應用程序:只需要開發應用程序的邏輯
        mysql:編寫好存儲過程,以供應用程序調用

        優點:開發效率,執行效率都高
        缺點:考慮到人為因素、跨部門溝通等問題,會導致擴展性差

    2、
        應用程序:除了開發應用程序的邏輯,還需要編寫原生sql
        mysql:

        優點:比方式1,擴展性高(非技術性的)
        缺點:
            1、開發效率,執行效率都不如方式1
            2、編寫原生sql太過於復雜,而且需要考慮到sql語句的優化問題


    3、
        應用程序:開發應用程序的邏輯,不需要編寫原生sql,基於別人編寫好的框架來處理數據,ORM
        mysql:

        優點:不用再編寫純生sql,這意味著開發效率比方式2高,同時兼容方式2擴展性高的好處
        缺點:執行效率連方式2都比不過
03 創建存儲過程

delimiter $$
create procedure p1(
    in m int,
    in n int,
    out res int
)
begin
    select tname from teacher where tid > m and tid < n;
    set res=0;
end $$
delimiter ;

# 如何用存儲過程
#1、直接在mysql中調用
set @res=10
call p1(2,4,10);
#查看結果
select @res;

#2、在python程序中調用


#3、事務的使用
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 ;



delimiter //
create PROCEDURE p6(
    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 user set balance=1010 where id = 2;
        update user set balance=1090 where id =3;
    COMMIT;

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

END //
delimiter ;

4,在python 中調用存儲過程
# import pymysql
#
# conn=pymysql.connect(
#     host=‘127.0.0.1‘,
#     port=3306,
#     user=‘root‘,
#     password=‘123‘,
#     charset=‘utf8‘,
#     database=‘db42‘
# )
#
# cursor=conn.cursor(pymysql.cursors.DictCursor)
#
# cursor.callproc(‘p1‘,(2,4,10)) #@_p1_0=2,@_p1_1=4,@_p1_2=10
#
#
# print(cursor.fetchall())
#
# cursor.execute(‘select @_p1_2;‘)
# print(cursor.fetchone())
#
# cursor.close()
# conn.close()



# import pymysql
#
# conn=pymysql.connect(
#     host=‘127.0.0.1‘,
#     port=3306,
#     user=‘root‘,
#     password=‘123‘,
#     charset=‘utf8‘,
#     database=‘db44‘
# )
#
# cursor=conn.cursor(pymysql.cursors.DictCursor)
#
# cursor.callproc(‘p6‘,(100,)) #@_p5_0 = 100
#
# cursor.execute(‘select @_p6_0‘)
# print(cursor.fetchone())
#
# cursor.close()
# conn.close()
五,函數
1、強調:mysql內置的函數只能在sql語句中使用
mysql> select date_format(sub_time,%Y-%m),count(id) from blog group by date_format(sub_time,%Y-%m);
六,流程控制
 1.條件語句
   delimiter //
   create procedure proc_if()
   begin
        declare i int default 0;
        if i=1then
            select 1;
        elseif i = 2 then
             select 2;
        else
              select 7;
        end if;
   end //
   delimiter;

    2,循環語句
    delimiter //
    create procedure proc_while()
    being

          declare num int;
          set num = 0;
          where num<10 do
                 SELECT
            num ;
        SET num = num + 1 ;
    END WHILE ;

END //
delimiter ;
  3,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 ;

    4,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

select
case
when name = egon then
    name
when name = alex then
    concat(name,_BIGSB)
else
    concat(name,_SB)
end

from emp;





視圖,觸發器,事務,存儲過程,函數,流程控制,