日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL之视图、触发器、事务、存储过程

發(fā)布時(shí)間:2025/3/15 数据库 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL之视图、触发器、事务、存储过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.cnblogs.com/linhaifeng/articles/7495918.html

視圖

? 試圖就是一個(gè)虛擬表(非真實(shí)存在),本質(zhì)就是【根據(jù)sql語句獲取動(dòng)態(tài)的數(shù)據(jù)集,并為其命名】,用戶使用時(shí)只需要使用名稱即可獲取數(shù)據(jù)集,可將該數(shù)據(jù)集當(dāng)作表來使用。

''' what: 視圖是由一張表或多張表的查詢結(jié)果構(gòu)成的一張?zhí)摂M表 why: 將復(fù)雜常用的查詢結(jié)果保留下來重復(fù)使用 | 將一張大表拆分成多張小表語法: create [or replace] view 視圖名[(查詢字段別名們)] as 查詢語句 create view new_emp as (select * from emp);注: 1.查詢字段別名們 要與 查詢語句的查詢字段對(duì)應(yīng) 2.create or replace: 操作視圖沒有則創(chuàng)建、有則替換 create or replace view new_emp(id,姓名,工資) as (select id,name,salary from emp where dep_id = 2);視圖的修改:alter 等價(jià)于 create or replace, 且語法一致 alter view new_emp(id,姓名,工資) as (select id,name,salary from emp where dep_id = 1);視圖中字段的操作:不允許alter操作字段 alter table new_emp rename new_emp1; alter view new_emp modify id tinyint;視圖中記錄的操作:等價(jià)于普通表,完成增刪改查 update new_emp set 姓名='san' where id = 3; delete from new_emp where id = 3; insert into new_emp(id, 姓名, 工資) values (10, "Bob", 10000); # 操作的是實(shí)體表, 虛擬表要重新創(chuàng)建才能拿到最新數(shù)據(jù)視圖的刪除: drop view 視圖名;總結(jié): 虛擬表作用 -- 查詢 '''

觸發(fā)器

使用觸發(fā)器可以定制用戶對(duì)表進(jìn)行【增刪改】操作時(shí)前后的行為(不報(bào)包括查詢)

''' what:在表發(fā)生數(shù)據(jù)更新時(shí),會(huì)自動(dòng)觸發(fā)的功能稱之為觸發(fā)器 why:當(dāng)一個(gè)表在發(fā)生數(shù)據(jù)更新時(shí),需要去完成一些操作,可以為具體數(shù)據(jù)更新的方式添加觸發(fā)器語法: delimiter // create trigger 觸發(fā)器名 before|after insert|update|delete on 表名 for each row begin 需要觸發(fā)執(zhí)行的sql代碼們 end // delimiter ;# 觸發(fā)器名: t1_before_insert_tri注:delimiter是用來修改sql的語句結(jié)束標(biāo)識(shí)符刪除觸發(fā)器:drop trigger 觸發(fā)器名; ''' # 插入前 CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW BEGIN... END# 插入后 CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW BEGIN... END# 刪除前 CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW BEGIN... END# 刪除后 CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW BEGIN... END# 更新前 CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW BEGIN... END# 更新后 CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW BEGIN... END# 刪除觸發(fā)器drop trigger tri_after_insert_cmd; # cmd表 create table cmd (id int primary key auto_increment,user char(32),priv char(10),cmd char (64),sub_time datetime, # 提交時(shí)間success enum ('yes', 'no') # 0代表執(zhí)行失敗 ); # 錯(cuò)誤日志表 create table errlog (id int primary key auto_increment,err_cmd char(64),err_time datetime ); # 創(chuàng)建觸發(fā)器 delimiter // create trigger trigger1 after insert on cmd for each row begin # new就是cmd當(dāng)前插入的那條記錄(對(duì)象) if new.success = "no" then # 等待值判斷只有一個(gè)等號(hào)insert into errlog values(null, new.cmd, new.sub_time); end if; end // delimiter ;# 往表cmd中插入記錄,觸發(fā)觸發(fā)器,根據(jù)IF的條件決定是否插入錯(cuò)誤日志 insert into cmd(user, priv, cmd, sub_time, success) values('egon', '0765', 'ls -l /etc', now(), 'yes'),('jerry', '0852', 'cat /etc/passwd', now(), 'no'),('kevin', '0867', 'useradd xxx', now(), 'no'),('owen', '0912', 'ps aux', now(), 'yes'); # 查看cmd數(shù)據(jù)信息 select * from cmd; # 查看錯(cuò)誤日志表中的記錄是否有自動(dòng)插入 select * from errlog;

? 觸發(fā)器用戶無法直接調(diào)用,而是由對(duì)表的【增刪改】操作被動(dòng)引發(fā)的

事務(wù)

事務(wù)用于將某些操作的多個(gè)SQL作為原子性操作,一旦有某一個(gè)出現(xiàn)錯(cuò)誤,即可回滾到原來的狀態(tài),從而保證數(shù)據(jù)庫數(shù)據(jù)完整性

''' what:事務(wù)是邏輯上的一組操作,要么都成功,要么都失敗 why:很多時(shí)候一個(gè)數(shù)據(jù)操作,不是一個(gè)sql語句就完成的,可能有很多個(gè)sql語句,如果部分sql執(zhí)行成功而部分sql執(zhí)行失敗將導(dǎo)致數(shù)據(jù)錯(cuò)亂 eg:轉(zhuǎn)賬 => 轉(zhuǎn)入轉(zhuǎn)出均成功,才能認(rèn)為操作成功事務(wù)的使用: start transaction; --開啟事物,在這條語句之后的sql將處在同一事務(wù),并不會(huì)立即修改數(shù)據(jù)庫 commit;--提交事務(wù),讓這個(gè)事物中的sql立即執(zhí)行數(shù)據(jù)的操作, rollback;--回滾事務(wù),取消這個(gè)事物,這個(gè)事物不會(huì)對(duì)數(shù)據(jù)庫中的數(shù)據(jù)產(chǎn)生任何影響事務(wù)的四大特性: 1.原子性:事務(wù)是一組不可分割的單位,要么同時(shí)成功,要么同時(shí)不成功 2.一致性:事物前后的數(shù)據(jù)完整性應(yīng)該保持一致(數(shù)據(jù)庫的完整性:如果數(shù)據(jù)庫在某一時(shí)間點(diǎn)下,所有的數(shù)據(jù)都符合所有的約束,則稱數(shù)據(jù)庫為完整性的狀態(tài)) 3.隔離性:事物的隔離性是指多個(gè)用戶并發(fā)訪問數(shù)據(jù)時(shí),一個(gè)用戶的事物不能被其它用戶的事務(wù)所干擾,多個(gè)并發(fā)事務(wù)之間數(shù)據(jù)要相互隔離 4.持久性:持久性是指一個(gè)事物一旦被提交,它對(duì)數(shù)據(jù)的改變就是永久性的,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對(duì)其有任何影響事務(wù)的用戶隔離級(jí)別: 數(shù)據(jù)庫使用者可以控制數(shù)據(jù)庫工作在哪個(gè)級(jí)別下,就可與防止不同的隔離性問題 read uncommitted --不做任何隔離,可能臟讀,幻讀 read committed --可以防止臟讀,不能防止不可重復(fù)讀,和幻讀, Repeatable read --可以防止臟讀,不可重復(fù)讀,不能防止幻讀 Serializable --數(shù)據(jù)庫運(yùn)行在串行化實(shí)現(xiàn),所有問題都沒有,就是性能低修改隔離級(jí)別: select @@tx_isolation;--查詢當(dāng)前級(jí)別 set[session|global] transaction isolation level ....;修改級(jí)別 實(shí)例: set global transaction isolation level Repeatable read; 注:修改后重新連接服務(wù)器生效 ''' #準(zhǔn)備數(shù)據(jù) create table account(id int primary key auto_increment,name varchar(20),money double ); insert into account values(1,'owen',10000),(2,'egon',1000),(3,'jerry',1000),(4,'kevin',1000);# egon向owen借1000塊錢 # 未使用事務(wù) update account set money = money - 1000 where id = 1; update account set moneys = money + 1000 where id = 2; # money打錯(cuò)了導(dǎo)致執(zhí)行失敗# 在python中使用事務(wù)處理 from pymysql.err import InternalError sql = 'update account set money = money - 1000 where id = 1;' sql2 = 'update account set moneys = money + 1000 where id = 2;' # money打錯(cuò)了導(dǎo)致執(zhí)行失敗 try:cursor.execute(sql)cursor.execute(sql2)conn.commit() # 提交事務(wù) except InternalError:print("轉(zhuǎn)賬失敗")conn.rollback()# 回滾操作

存儲(chǔ)過程

一、簡(jiǎn)介

? 存儲(chǔ)過程包含了一系列可執(zhí)行的sql語句,存儲(chǔ)過程存放于mysql中,通過調(diào)用它的名字可執(zhí)行其內(nèi)部的一堆sql語句

? 優(yōu)點(diǎn):

#1. 用于替代程序?qū)懙腟QL語句,實(shí)現(xiàn)程序與sql解耦#2. 基于網(wǎng)絡(luò)傳輸,傳別名的數(shù)據(jù)量小,而直接傳sql數(shù)據(jù)量大

? 缺點(diǎn):程序員擴(kuò)展功能不方便

程序與數(shù)據(jù)庫結(jié)合使用的三種方式

#方式一:MySQL:存儲(chǔ)過程程序:調(diào)用存儲(chǔ)過程#方式二:MySQL:程序:純SQL語句#方式三:MySQL:程序:類和對(duì)象,即ORM(本質(zhì)還是純SQL語句)

二、創(chuàng)建簡(jiǎn)單的存儲(chǔ)過程(無參)

delimiter // create procedure p1() BEGINselect * from blog;INSERT into blog(name,sub_time) values("xxx",now()); END // delimiter ;#在mysql中調(diào)用 call p1() #在python中基于pymysql調(diào)用 cursor.callproc('p1') print(cursor.fetchall())

三、創(chuàng)建存儲(chǔ)過程(有參)

對(duì)于存儲(chǔ)過程,可以接收參數(shù),其參數(shù)有三類:#in 僅用于傳入?yún)?shù)用 #out 僅用于返回值用 #inout 既可以傳入又可以當(dāng)作返回值

① in:傳入?yún)?shù)

delimiter // create procedure p2(in n1 int,in n2 int ) BEGINselect * from blog where id > n1; END // delimiter ;#在mysql中調(diào)用 call p2(3,2)#在python中基于pymysql調(diào)用 cursor.callproc('p2',(3,2)) print(cursor.fetchall())

② out:返回值

delimiter // create procedure p3(in n1 int,out res int ) BEGINselect * from blog where id > n1;set res = 1; END // delimiter ;#在mysql中調(diào)用 set @res=0; #0代表假(執(zhí)行失敗),1代表真(執(zhí)行成功) call p3(3,@res); select @res;#在python中基于pymysql調(diào)用 cursor.callproc('p3',(3,0)) #0相當(dāng)于set @res=0 print(cursor.fetchall()) #查詢select的查詢結(jié)果cursor.execute('select @_p3_0,@_p3_1;') #@p3_0代表第一個(gè)參數(shù),@p3_1代表第二個(gè)參數(shù),即返回值 print(cursor.fetchall())

③ inout 可傳值可返回

delimiter // create procedure p4(inout n1 int ) BEGINselect * from blog where id > n1;set n1 = 1; END // delimiter ;#在mysql中調(diào)用 set @x=3; call p4(@x); select @x;#在python中基于pymysql調(diào)用 cursor.callproc('p4',(3,)) print(cursor.fetchall()) #查詢select的查詢結(jié)果cursor.execute('select @_p4_0;') print(cursor.fetchall())

四、執(zhí)行存儲(chǔ)過程

① 在MySQL中執(zhí)行存儲(chǔ)過程

-- 無參數(shù) call proc_name()-- 有參數(shù),全in call proc_name(1,2)-- 有參數(shù),有in,out,inout set @t1=0; set @t2=3; call proc_name(1,2,@t1,@t2)

② 在python中基于MySQL執(zhí)行存儲(chǔ)過程

#!/usr/bin/env python # -*- coding:utf-8 -*- import pymysqlconn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123', db='t1') cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) # 執(zhí)行存儲(chǔ)過程 cursor.callproc('p1', args=(1, 22, 3, 4)) # 獲取執(zhí)行完存儲(chǔ)的參數(shù) cursor.execute("select @_p1_0,@_p1_1,@_p1_2,@_p1_3") result = cursor.fetchall()conn.commit() cursor.close() conn.close()print(result)

五、刪除存儲(chǔ)過程

drop procedure proc_name;

六、小結(jié)

''' what:用于完成指定功能的sql語句塊,類似于Python中的函數(shù) why:將能指定功能的sql語句塊建立成存儲(chǔ)過程,不僅將sql語句邏輯化了,更是功能化了,那我們要完成相同的事,只需要重復(fù)使用建立的存儲(chǔ)過程,不就需要再重復(fù)書寫sql語句了 # 總結(jié): 存儲(chǔ)過程可以讓sql語句具有 復(fù)用性, 從而提高開發(fā)效率語法: delimiter // create procedure 存儲(chǔ)過程名(輸入輸出類型1 參數(shù)名1 參數(shù)類型1(寬度), ... ,輸入輸出類型n 參數(shù)名n 參數(shù)類型n(寬度) ) begin sql語句塊 end // delimiter ; 注: 1.輸入輸出類型:in | out | inout 2.call 存儲(chǔ)過程名(實(shí)參們)來調(diào)用存儲(chǔ)過程案例: set @res = null; # 定義空值變量, 用來接收存儲(chǔ)過程的執(zhí)行結(jié)果 delimiter // create procedure user_info(in b int, in l int, out res char(20)) begin select * from emp limit b, l; set res = 'success'; end // delimiter ; call user_info(2, 3, @res); # 調(diào)用存儲(chǔ)過程, 傳入相應(yīng)的實(shí)參 select @res; # 查看存儲(chǔ)過程的執(zhí)行結(jié)果變量的使用: 1.賦值變量:set @變量名 = 變量值 2.使用變量:@變量名 | select @變量名 3.刪除變量:set @變量名 = null三種開發(fā)方式: 1. 業(yè)務(wù)邏輯 + 存儲(chǔ)過程:高執(zhí)行與開發(fā)效率,低耦合 | 不易移植,人員成本高 2. 業(yè)務(wù)邏輯 + 原生sql:人員成本低 | 開發(fā)難度大 3. 業(yè)務(wù)邏輯 + ORM:高開發(fā)效率,對(duì)象化操作數(shù)據(jù)庫,可移植 | 性能消耗加大,多表聯(lián)查、復(fù)雜條件會(huì)復(fù)制化ORM存儲(chǔ)過程的操作: 1.查看 select routine_name, routine_type from information_schema.routines where routine_schema='數(shù)據(jù)庫名';eg: select routine_name, routine_type from information_schema.routines where routine_schema='db2';2.刪除 drop procedure [if exists] 數(shù)據(jù)庫名.存儲(chǔ)過程名 ''' delimiter // create procedure send_money( out p_return_code char(20) ) begin # 異常處理declare exit handler for sqlexception begin # error set p_return_code = '錯(cuò)誤異常'; rollback; end; # exit 也可以換成continue 表示發(fā)送異常時(shí)繼續(xù)執(zhí)行declare exit handler for sqlwarning begin # warning set p_return_code = '警告異常'; rollback; end; start transaction;update account set money = money - 1000 where id = 1;update account set money = moneys + 1000 where id = 2; # moneys字段導(dǎo)致異常commit; # success set p_return_code = '轉(zhuǎn)賬成功'; # 代表執(zhí)行成功 end // delimiter ;# 在mysql中調(diào)用存儲(chǔ)過程 set @res=null; call send_money(@res); select @res;

轉(zhuǎn)載于:https://www.cnblogs.com/prodigal/p/10263421.html

總結(jié)

以上是生活随笔為你收集整理的MySQL之视图、触发器、事务、存储过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。