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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql事务变量_mysql学习四之事务、变量、触发器、函数、存储过程

發布時間:2024/10/8 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql事务变量_mysql学习四之事务、变量、触发器、函数、存储过程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需求:有一張銀行賬戶表,有A用戶給B用戶轉賬;A賬戶先減少,B賬戶增加,但是A操作完之后斷電了。

解決方案:A減少錢,但是不要立即修改數據表;B收到錢之后,同時修改數據表

事務安全

事務:transaction,一系列要發生的連續的操作

事務安全:一種保護連續操作同時滿足(實現)的一種機制

事務安全的意義:保證數據操作的完整性

--創建一個賬戶表

create table my_account(

number char(16) not null unique comment '賬戶',

name varchar(20) not null,

money decimal(10) default 0.0 comment '賬戶余額'

)charset utf8;

insert into my_account values('0000000000000001','張三',1000),('0000000000000002','李四',1000);

alter table my_account add id int primary key auto_increment first;

update my_account set money = money - 1000 where id= 1;

事務操作

事務操作分為兩種:自動事務(默認的),手動事務

手動事務:操作流程

1、開啟事務:告訴系統以下所有的操作(寫)不要直接寫入到數據表,先存到事務日志

--開啟事務

start transaction;

2、進行事務操作:一系列操作

a)李四賬戶減少

update my_account set money = money - 1000 where id = 2;

b)張三賬戶增加

update my_account set money = money + 1000 where id = 1;

3、關閉事務:選擇性的將日志文件中操作的結果保存到數據表(同步)或者說

直接清空事務日志(原來操作全部清空)

a)提交事務:同步數據表(操作成功)commit;

b)回滾事務;直接清空(操作失敗) rollback;

--提交事務

commit;

事務原理

開啟事務后,后續的所用操作(寫);會先寫到臨時日志文件,

接收SQL語句,執行SQL語句;結果先寫入到臨時日志文件;

查詢操作:會從數據表查詢,經過臨時日志文件結果加工后返回

事務結束:commint或rollback,清空臨時日志文件,commit會同步到數據表,

rollback是直接清空

如果斷開連接,臨時事務文件會自動清空。

回滾點

在某個成功的操作完成之后,后續的操作有可能成功有可能失敗,但是不管

成功還是失敗,前面操作都已經成功;可以在當前成功的位置,設置一個點;

可以供后續失敗操作返回該位置,而不是返回所有操作,這個點稱為回滾點。

設置回滾點語法:savepoint 回滾點名字

回到回滾點語法:rollback to 回滾點名字

--回滾點操作

--開啟事務

start transaction;

--事務處理1:張三加錢

update my_account set money=money+10000 where id = 1;

--查看結果

select * from my_account;

--設置回滾點

savepoint sp1;

--銀行扣稅

update my_account set money=money-10000*0.05 where id=2; --錯誤

--查看結果

select * from my_account;

--回滾到回滾點

rollback to sp1;

--查看結果

select * from my_account;

--繼續操作

update my_account set money=money-10000*0.05 where id=1;

--查看結果

select * from my_account;

--提交事務

commit;

事務特性:四大特性

A:原子性,事務整個操作是一個整體,不可分割,要么全部成功,要么全部失敗

C:一致性,事務操作的前后,數據表的數據沒有變化

I:隔離性,事務操作是相到隔離不受影響的

D:持久性,數據一旦提交,不可改變,永久的改變數據表數據

鎖機制:innodb默認是行鎖,但是如果在事務操作的過程中,沒有使用到索引,

那么系統會自動全表檢索數據,自動升級為表鎖。

行鎖:只有當前行被鎖住,別的用戶不能操作

表鎖:整張表被鎖住,別的用戶都不能操作。

變量

變量分為系統變量和自定義變量

系統變量:系統自定義好的變量,系統變量是用來控制服務器的表現的,如

autocommit,auto_increment_increment等

查看系統變量

show variables ; --查看所有系統變量

查看具體變量值:任何一個有數據返回的內容都是由select查看

select @@變量名;

--查看變量值

select @@version,@@autocommit,@@auto_increment_offset;

修改系統變量

分為兩種方式:會話級別和全局級別和全局級別

會話級別:臨時修改

--修改會話級別變量 ,當前客戶端當次連接有效

set 變量名 = 值 ; set @@變量名 = 值;

set autocommit = 0 ;

全局級別:一次修改,永久生效(對所有客戶端生效)

set global 變量名 = 值;

自定義變量

系統為了區分系統變量,規定用戶自定義變量必須使用一個@符號

set @變量名=值;

set @name = '張三';

select @name;

mysql定義的一個賦值符號:=

set @age := 19;

select @age;

mysql允許從數據表中獲取數據,然后賦值給變量:兩種方式

1、邊賦值,邊查看結果(只能用:=,=號會解析為比較)

select @變量名 := 字段名 from 數據源; --從字段中取值賦值給變量名

--從表中獲取數據賦值給變量

select @name := name from my_student;

2、只有賦值不看結果,要求很嚴格:數據記錄只能有一條記錄

select 字段表 from 數據源 into @變量名

select name,age from my_student where id=2 into @name,@age;

所有自定義的變量都是會話級別:當前客戶端當次連接有效

所有自定義變量不區分數據庫(用戶級別)

需求:有兩張,一張訂單表,一張商品表,每生成一個訂單,意味著商品的庫存要

減少

觸發器

事先為某張表綁定好一段代碼,當表中的某些內容發生改變的時候(增刪改)系統

會自動觸發代碼執行。

事件類型,觸發時間,觸發對象

事件類型:增刪改,三種類型 insert delete update

觸發時間:前后,兩種 before after

觸發對象:表中的每一條記錄(行)

一張表中只能擁有一種觸發時間的一種類型的觸發器;最多一張表能有6個觸發器

創建觸發器

在mysql高級結構中:沒有大括號,都是用對應的字符符號代替

基本語法

--臨時修改語句結束符

delimiter 自定義符號:后續代碼中只有碰到自定義符號才結束

create trigger 觸發器名字 觸發時間 事件類型 on 表名 for each row

begin --代表左大括號;開始

...里面就是觸發器的內容:每行內容都必須使用語句結束符,分號

end --代表右帶括號:結束

--語句結束符號

自定義符號

--將臨時修改修正過來

delimiter

--創建表

create table my_goods(

id int primary key auto_increment,

name varchar(20) not null,

price decimal(10,2) default 1,

inv int comment '庫存'

)charset utf8;

insert into my_goods values(null,'iphone6s',5288,100),(null,'s6',5300,100);

create table my_order(

id int primary key auto_increment,

g_id int not null comment '商品ID',

g_number int comment '商品數量'

)charset utf8;

--觸發器:訂單生成一個,商品庫存減少

--臨時修改語句結束符

delimiter $$

create trigger after_order after insert on my_order for each row

begin

update my_goods set inv = inv - 1 where id = 2;

end

$$

delimiter ;

查看觸發器

查看所有觸發器或者模糊匹配

show triggers\G;

--查看觸發器創建語句

show create trigger 觸發器名字;

show create trigger after_order\G

所有觸發器都會存到一個系統表中information_schema.triggers

select * from information_schema.triggers

使用觸發器

不需要手動調用,而是當某種情況發生時,會自動觸發

--訂單插入記錄會自動觸發

--觸發器工作了,訂單生成之后,對應商品數量減少了

--當前商品減少的,不是訂單中產生的商品;而是固定的商品(不合理)

--插入訂單

insert into my_order values(null,1,2);

修改觸發器&刪除觸發器

觸發器不能修改,只能先刪除后新增

drop trigger 觸發器名字;

--刪除觸發器

drop trigger after_order;

觸發器記錄

不管觸發器是否觸發了,只要當前某種操作準備執行,系統就會將當前要操作的記錄的當前狀態

和即將執行之后新的狀態給分別保留下來,供觸發器使用:其中,要操作的當前狀態保存到old中,

操作之后的可能形態保存給new

old代表的是舊記錄,new代表的是新記錄

刪除的時候沒有new,插入的時候沒有old

old和new代表記錄本身,任何一條記錄除了數據,還有字段名字

使用方式old.字段名/ new.字段名(new代表假設發生之后的結果)

delimiter $$

create trigger after_order after insert on my_order for each row

begin

update my_goods set inv = inv - new.g_number where id = new.g_id;

end

$$

delimiter ;

insert into my_order values(null,1,2);

代碼執行結構

三種:順序結構 、分支結構、循環結構

分支結構

實現準備多個代碼塊,按照條件選擇性的執行某段代碼

在mysql中只有if分支

基本語法

if 條件判斷 then

--滿足條件要執行的代碼

else

--不滿足條件要執行的代碼

end if;

觸發器結合If分支,判斷商品庫存是否足夠,不夠不能生成商品訂單

--庫存不夠:觸發器沒有提供一個能夠阻止事件發生的能力,暴力報錯

delimiter %%

create trigger before_order before insert on my_order for each row

begin

select inv from my_goods where id = new.g_id into @inv;

if @inv < new.g_number then

insert into XXX values(XXX);

end if;

end

%%

delimiter ;

--插入訂單

insert into my_order values(null,1,1000);

循環結構

某段代碼在指定條件重復執行

while循環

while 條件判斷 do

--滿足條件要執行的代碼

--變更循環條件

end while;

循環控制:在循環內部進行循環判斷和控制

mysql中沒有對應的continue和break;但是有替代呂

iterate 迭代,類似continue ,后面的代碼不執行,循環重新來過

leave 離開 ,類似break;

使用方式 iterate/leave 循環名字;

--定義循環名字

循環名字:while 條件 do

--循環體

--循環控制

leave/iterate 循環名字

end while;

函數

將一段代碼塊封裝到一個結構中,在需要執行代碼的時候,調用結構執行即可(代碼復用)

分為兩類:系統函數和自定義函數

系統函數:直接調用即可

任何函數都有返回值,因此函數的調用是通過select調用。

mysql中字符串的基本單位,最常用的是字符

substring 字符串截取,字符為單位substring(str,pos,len);

char_length 字符長度

length字節長度

instr判斷字符串是否在某個具體字符串中存在

lpad左填充,將字符串,按照某個指定的填充方式,填充指定長度

insert 字符串替換

strcmp 字符串比較

--定義兩個變量

set @cn = '世界你好';

set @en = 'hello world';

--字符串截取,mysql中字符串下標從1開始,截取單位為字符

select substring(@cn,1,1);

select substring(@en,1,1);

--字符長度

select char_length(@cn),char_length(@en),length(@cn),length(@en);

--字符串尋找,0代表沒有找到

select instr(@cn,'界'),instr(@en,'ll'),instr(@cn,'知道');

--字符串填充

select lpad(@cn,20,'歡迎'),lpad(@en,20,'hello');

--字符串替換

select insert(@en,3,3,'y'),@en;

自定義函數

函數要素:函數名、參數列表(形參和實參),返回值,函數體

創建語法

create function 函數名([形參列表]) returns 數據類型 --規定要返回的數據類型

begin

--函數體

--返回值 return類型(指定數據類型)

end

--創建函數

create function display1() returns int

return 100;

--調用函數

select display1();

--查看所有函數

show function status [like ''];

函數屬于指定數據,只有在對應數據庫下調用

查看函數的創建

show create function 函數名;

show create function display1;

修改函數&刪除函數

函數不能修改,先刪除后新增

drop function 函數名;

drop function display1;

函數參數

參數分為兩種:定義時的參數叫形參,

--函數:計算1-指定數之間的和

-- 求和:任何變量要修改必須使用set關鍵字

--@定義的變量是全局變量,沒有的是局部變量

delimiter $$

create function display1(int_1 int) returns int

begin

set @i = 1 ;

set @res = 0 ;

while @i <= int_1 do

set @res =@res+ @i;

set @i = @i+1;

end while;

return @res;

end

$$

delimiter ;

在函數內部使用@定義的變量在函數外部也可以訪問

作用域

mysql中的作用域與JS中的作用域一樣

全局變量可以在任何地方使用;局部變量只能在函數內部使用

全局變量:使用set關鍵字定義,使用@符號標志

局部變量:使用declare關鍵字聲明,沒有@符號;所有的局部變量的聲明

--求和:1-指定數之間的和,要求5的倍數不加

delimiter $$

create function display2(int_1 int) returns int

begin

declare i int default 1 ;

declare res int default 0 ;

mywhile:while i <= int_1 do

if i%5=0 then

set i = i+1;

iterate mywhile;

end if;

set res = res +i;

set i = i+1;

end while;

return res;

end

$$

delimiter ;

存儲過程

存儲過程是一種沒有返回值的函數

創建過程

create procedure 過程名字([參數列表])

begin

--過程體

end

--創建過程

--假設過程中需要顯示數據:使用select

create procedure pro1()

select * from my_student;

查看過程

查看所有過程

show procedure status [like ''];

--查看過程創建語句

show create procedure pro1;

調用過程

過程沒有返回值,select是不能訪問的

過程有一個專門的調用關鍵字 call

call pro1();

修改過程&刪除過程

過程不能修改,只能先刪除后新增

drop procedure 過程名;

drop procedure pro1;

過程參數

函數的參數需要數據類型指定,過程比函數更嚴格

過重還有自己的類型限定:三種類型

in:數據只是從外部傳入內部使用(值傳遞);可以是數值,也可以是變量

out:只允許過程內部使用(不用外部數據),給外部使用的(引用傳遞,外部的數據會被

先清空才會進入到內部),只以是變量

inout:外部可以在內部使用,內部修改也可以給外部使用;典型的引用傳遞,只能是變量

基本使用:

create procedure 過程名(in 形參名字 數據類型,out 形參名字 數據類型,inout 形參名字 數據類型)

--過程參數

--int_2的值一定是null,Out數據會被先清空

delimiter $$

create procedure pro1(in int_1 int,out int_2 int,inout int_3 int)

begin

select int_1,int_2,int_3;

end

$$

delimiter ;

調用 :out 和inout類型的參數必須傳入變量而不是數值

set @int_1=1;

set @int_2=2;

set @int_3=3;

select @int_1,@int_2,@int_3;

call pro1(@int_1,@int_2,@int_3);

--局部變量和全局變量沒有關系

delimiter $$

create procedure pro2(in int_1 int,out int_2 int,inout int_3 int)

begin

select int_1,int_2,int_3;

set int_1 = 10 ;

set int_2 = 100;

set int_3 = 1000;

select int_1,int_2,int_3;

select @int_1,@int_2,@int_3;

set @int_1 = 'a';

set @int_2 = 'b';

set @int_3 = 'c';

select int_1,int_2,int_3;

select @int_1,@int_2,@int_3;

end

$$

delimiter ;

select @int_1,@int_2,@int_3;

最后:在存儲過程調用結束之后,系統會將局部變量重新返回給全局變量,只有out,inout;

分享到:

2016-03-23 18:49

瀏覽 961

分類:數據庫

評論

總結

以上是生活随笔為你收集整理的mysql事务变量_mysql学习四之事务、变量、触发器、函数、存储过程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。