《MySQL數(shù)據(jù)庫應(yīng)用實戰(zhàn)教程(微課版)》-第7、8章-數(shù)據(jù)庫編程、數(shù)據(jù)庫開發(fā)體驗_第1頁
《MySQL數(shù)據(jù)庫應(yīng)用實戰(zhàn)教程(微課版)》-第7、8章-數(shù)據(jù)庫編程、數(shù)據(jù)庫開發(fā)體驗_第2頁
《MySQL數(shù)據(jù)庫應(yīng)用實戰(zhàn)教程(微課版)》-第7、8章-數(shù)據(jù)庫編程、數(shù)據(jù)庫開發(fā)體驗_第3頁
《MySQL數(shù)據(jù)庫應(yīng)用實戰(zhàn)教程(微課版)》-第7、8章-數(shù)據(jù)庫編程、數(shù)據(jù)庫開發(fā)體驗_第4頁
《MySQL數(shù)據(jù)庫應(yīng)用實戰(zhàn)教程(微課版)》-第7、8章-數(shù)據(jù)庫編程、數(shù)據(jù)庫開發(fā)體驗_第5頁
已閱讀5頁,還剩93頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

項目7數(shù)據(jù)庫編程目錄任務(wù)1學習MySQL編程任務(wù)1學習MySQL編程MySQL編程概述【實訓7-1】MySQL語言基礎(chǔ)【實訓7-2】MySQL流程控制【實訓7-3】使用內(nèi)置函數(shù)【實訓7-4】使用游標任務(wù)2存儲函數(shù)任務(wù)3使用存儲過程任務(wù)4使用觸發(fā)器任務(wù)5了解事務(wù)和鎖7.1.1

MySQL編程概述

編程語言的基礎(chǔ)是關(guān)鍵字、數(shù)據(jù)類型、變量和常量、運算符、表達式,以及流程控制,下面分別講解。1.關(guān)鍵字關(guān)鍵字是有特殊含義的單詞,MySQL

5.5的關(guān)鍵字有565個,其中包括226個保留字保留字(226個):不能用于表名或列名的關(guān)鍵字,例如Select和Delete等非保留關(guān)鍵字(339個):雖然有特殊含義,但可以用于表名或列名中7.1.1

MySQL編程概述(續(xù)一)7.1.1

MySQL編程概述(續(xù)二)2.數(shù)據(jù)類型

變量的數(shù)據(jù)類型與列的數(shù)據(jù)類型相同,見附錄A,并參見項目2的“任務(wù)2理解MySQL的數(shù)據(jù)類型”一節(jié)對數(shù)據(jù)類型的講解3.命名需要命名的有表名、列名、變量名,以及函數(shù)名等命名原則不要與保留字以及非保留關(guān)鍵字(共500多個)相同應(yīng)該從名稱的前綴區(qū)分出名稱的類別,如表名、列名、變量名,以及函數(shù)名等名稱全部小寫,雖然SQL是大小寫不敏感的表7.2是本書使用的命名規(guī)范7.1.1

MySQL編程概述(續(xù)三)7.1.2【實訓7-1】MySQL語言基礎(chǔ)概述1.變量系統(tǒng)變量用戶變量局部變量2.字面常量【實訓7-1】7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)一)--格式一

Case表達式when等于值1時then結(jié)果1when等于值2時then結(jié)果2…else結(jié)果nend

case--格式二

Casewhen表達式1為真時then結(jié)果1when表達式2為真時then結(jié)果2…else結(jié)果nend

case3.運算符和表達式(1)常用運算符算術(shù)運算符、關(guān)系運算符等,與Java語言、Python以及C語言等基本相同(2)If運算符If(條件表達式,為真時的結(jié)果,為假時的結(jié)果)(3)Ifnull運算符Ifnull(值,值為空時的返回值)(4)Case運算符7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)二,系統(tǒng)變量)根據(jù)Jitor校驗器的要求,在dbForge上完成“【實訓7-1】MySQL語言基礎(chǔ)”1、系統(tǒng)變量系統(tǒng)變量是MySQL系統(tǒng)內(nèi)部定義的變量,保存了系統(tǒng)的配置參數(shù),以及軟件和硬件參數(shù)的值系統(tǒng)變量的命名:以@@為前綴(1)查詢指定系統(tǒng)變量的值Select

@@wait_timeout;(2)列出全部系統(tǒng)變量show

variables;結(jié)果有600多個系統(tǒng)變量,顯示時沒有前綴(3)模糊查找系統(tǒng)變量show

variables

like

"version%";查詢以version起始的系統(tǒng)變量,MySQL版本相關(guān)的信息注1:顯示時沒有前綴注2:不要修改系統(tǒng)變量的值,少數(shù)系統(tǒng)變量可以重新賦值,但還是不要這樣做注3:系統(tǒng)變量還分為全局(global)變量與會話(session)變量兩種,初學者不必區(qū)分它們7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)三,用戶變量)2、用戶變量用戶變量是用戶定義的變量,用于保存數(shù)據(jù),具有較長的生命周期用戶變量的命名:以@為前綴無需聲明,直接可用(1)例子一:用Set賦值Set

@text

=

"Hello";Select

@text;(2)例子二:用Select語句賦值,將查詢結(jié)果賦給用戶變量Select

sum(col_ammount),

avg(col_ammount)

into

@ammout,

@average

from

shop_order_head;Select

@ammout,

@average;7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)四,局部變量)3、局部變量局部變量是在語句塊(用begin和end定義語句塊)中聲明的變量,用于保存臨時數(shù)據(jù),它的生命周期很短局部變量的命名:無需前綴,但為了與表名列名等混淆,建議加上前綴var_局部變量必須先用Declare聲明,然后才能使用,語法格式如下Declare局部變量名數(shù)據(jù)類型default初始值;局部變量的例子局部變量是在語句塊中的,而語句塊又是在存儲程序(下面以存儲過程為例)中的Drop

procedure

if

exists

p_proc;--丟棄名為p_proc的存儲過程,如果它存在

Delimiter%%--指定新的分隔符Create

procedure

p_proc()--創(chuàng)建存儲過程,語句塊放在存儲過程中beginDeclare

var_tmp

int

default

5;Set

var_tmp

=

12;Select

var_tmp;end%%Delimiter;--恢復默認的分隔符(分號)運行存儲程序(此處為存儲過程)Call

p_proc();--運行存儲過程7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)五,比較)用戶變量的作用域是這個用戶,從賦值開始,直到用戶退出局部變量的作用域是語句塊,從聲明開始,直到語句塊結(jié)束局部變量與用戶變量的比較Drop

procedure

if

exists

p_proc;--丟棄名為p_proc的存儲過程,如果它存在

Delimiter%%--指定新的分隔符Create

procedure

p_proc()beginDeclare

var_tmp

int

default

12;--用戶變量--局部變量Set

@tmp

=

22;Select

var_tmp;end%%Delimiter

;--恢復默認的分隔符(分號)Call

p_proc();Select

@tmp;Select

var_tmp;最大的區(qū)別在于作用域--仍然可以訪問,并有原來的值--不能訪問,因為超出了作用域范圍7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)六,if和ifnull)If運算符If運算符類似于C/C++或Java語言中的三元運算符,語法格式如下。If(條件表達式,為真時的結(jié)果,為假時的結(jié)果)例如使用下述語句可以將以M、F表示的性別轉(zhuǎn)換為“男”和“女”。Select

col_name,if

(col_sex="M","男","女")from

shop_staff;Ifnull運算符Ifnull運算符判斷一個值是否為空。如果不為空返回該值,如果為空返回另一個值,語法格式如下。Ifnull(值,值為空時的返回值)例如下述語句,將列出所有手機號。如果手機號為空,則顯示“缺手機號”。Select

col_name,ifnull

(col_mobile,"缺手機號")from

shop_staff;與下述語句等價Select

col_name,if

(col_mobile

is

not

null,col_mobile,"缺手機號")from

shop_staff;7.1.2【實訓7-1】MySQL語言基礎(chǔ)(續(xù)七,case)Case運算符比較兩種方式第二種方式更加靈活,例如引用不同的列,有更靈活的條件Select

col_name,

col_inventory,

col_price,casewhen

col_price>=200

and

col_inventory<5

then"需補貨"when

col_price<200

and

col_inventory<10

then"需補貨"

else"庫存充足"endfrom

shop_goods;Select

col_name,case

col_sexwhen

"M"then"男"when

"F"then"女"

else"未知"endfrom

shop_staff;Select

col_name,casewhen

col_sex="M"then"男"when

col_sex="F"then"女"

else"未知"endfrom

shop_staff;編程概述——小結(jié)與其他編程語言比較,MySQL比較特別的有兩處變量分為系統(tǒng)變量、用戶變量和局部變量三種編程元素必須在語句塊中,而語句塊又必須在存儲程序中,即在下述代碼中Drop

procedure

if

exists

p_proc;--丟棄名為“p_proc”的存儲過程,如果它存在

Delimiter%%--指定新的分隔符Create

procedure

p_proc()--創(chuàng)建一個名為p_proc的存儲過程begin--編程元素(局部變量、流程控制等)的代碼寫在這里

end%%Delimiter;--恢復默認的分隔符(分號)Call

p_proc;--調(diào)用名為“p_proc”的存儲過程注:存儲程序有存儲函數(shù)、存儲過程等多種,后面將詳細講解7.1.3【實訓7-2】MySQL流程控制1.條件分支語句(1)If語句(2)Case語句注1:本節(jié)所有代碼都要放在存儲程序中的begin…end語句塊中才能運行

注2:If

運算符、Case

運算符與If

語句、Case

語句是不同的,前者用于表達式,后者用于流程控制Set

@id=3;If

@id=1

thenselect"語句1";elseif

@id=2

thenselect"語句2";elseselect"語句n";end

if;Set

@id=2;Casewhen

@id=1

thenselect"語句1";when

@id=2

thenselect"語句2";elseselect"語句n";end

case;【實訓7-2】7.1.3【實訓7-2】MySQL流程控制(續(xù)一,While循環(huán))2.循環(huán)語句之一:While循環(huán)語句語法格式如下。[標簽:]While循環(huán)條件表達式do語句塊;end

while;可以選擇用leave關(guān)鍵字強制退出當前循環(huán),或用iterate關(guān)鍵字強制進入下一次循環(huán)。兩個例子--計算1到100的累加和Declare

_i

int

default

0;Set

@sum

=

0;While

_i<100

doset

_i

=

_i

+

1;set

@sum

=

@sum

+

_i;end

while;Select

@sum;--計算1到100的累加和,用iterate短路,相當于計算1到50的累加和Declare

_i

int

default

0;Set

@sum

=

0;r:While

_i<100

do--用標簽r命名這個循環(huán)set

_i

=

_i

+

1;if

_i>50

theniterate

r;--跳過后面的循環(huán)體end

if;set

@sum

=

@sum

+

_i;end

while;Select

@sum;7.1.3【實訓7-2】MySQL流程控制(續(xù)二,Repeat循環(huán))--計算1到100的累加和Declare

_i

int

default

0;Set

@sum

=

0;Repeatset

_i

=

_i

+

1;set

@sum

=

@sum

+

_i;until

_i>=100--到達100后,結(jié)束循環(huán)

end

repeat;Select

@sum;2.循環(huán)語句之一:Repeat循環(huán)語句語法格式如下。[標簽:]Repeat語句塊;until結(jié)束條件表達式end

repeat;可以選擇用leave關(guān)鍵字強制退出當前循環(huán),或用iterate關(guān)鍵字強制進入下一次循環(huán)。兩個例子--計算1到100的累加和,用leave退出,相當于計算1到50的累加和Declare

_i

int

default

0;Set

@sum

=

0;r:Repeat--用標簽r命名這個循環(huán)set

_i

=

_i

+

1;if

_i>50

thenleave

r;--退出標簽r指定的循環(huán)end

if;set

@sum

=

@sum

+

_i;until

_i>=100--到達100后,結(jié)束循環(huán)end

repeat;Select

@sum;7.1.3【實訓7-2】MySQL流程控制(續(xù)三,Loop循環(huán))2.循環(huán)語句之一:Loop循環(huán)語句語法格式如下。標簽:Loop語句塊;end

loop;這是無限循環(huán),必須用leave關(guān)鍵字強制退出當前循環(huán),所以標簽是不能省略的一個例子--計算1到100的累加和Declare

_i

int

default

0;Set

@sum

=

0;r:Loop--用標簽r命名這個循環(huán)set

_i

=

_i

+

1;set

@sum

=

@sum

+

_i;if

_i>=100

thenleave

r;--退出標簽r指定的循環(huán)end

if;end

loop;Select

@sum;MySQL流程控制——小結(jié)3種循環(huán)的比較輔助關(guān)鍵字Leave:退出,提前結(jié)束循環(huán),類似于C/Java的breakIterate:短路,提前進入下一輪循環(huán),類似于C/Java的continue7.1.4【實訓7-3】使用內(nèi)置函數(shù)注意:字符串連接不能用加號,而必須用concat函數(shù),這個函數(shù)可以連接任意多個字符串1.統(tǒng)計函數(shù)在“項目4”的“4.4.4【實訓4-11】統(tǒng)計與分組統(tǒng)計”詳細討論過2.數(shù)學函數(shù)與其他編程語言類似Select

sqrt(3);--求平方根Select

round(3.14159,3);--保留3位小數(shù),四舍五入3.字符串函數(shù)【實訓7-3】7.1.4【實訓7-3】使用內(nèi)置函數(shù)(續(xù))3.字符串函數(shù)(續(xù))運行下述語句,觀察內(nèi)置函數(shù)的運行結(jié)果select

length("abc漢字");--運行結(jié)果是9(返回字節(jié)數(shù))select

char_length("abc漢字");--運行結(jié)果是5(返回字符數(shù))select

substring("12345678",2,3);--234select

substring("12345678",

2);--

2345678select

replace("12345678",

"23",

"abc");

--

1abc45678select

concat("12345678",

"23",

"abc");

--

1234567823abcselect

ascii("abc");

--

97select

char(97);

--

a注意:字符串連接不能用加號,要用concat函數(shù),這個函數(shù)可以連接任意多個字符串Select

concat("abc",

"xyz");

--

abcxyzSelect

concat("abc",

"xyz",

"123");

--

abcxyz123Select

concat("abc",

"xyz",

"123",

"abc");--

abcxyz123abc加號只用于算術(shù)加法運算,例如Select

12

+

15;

--

27Select

"12"+"15";--27,字符串中的數(shù)字轉(zhuǎn)換為數(shù)字類型后相加Select

‘a(chǎn)bc’+15;--15,0+15=15,字符串中的字母無法轉(zhuǎn)換,轉(zhuǎn)換結(jié)果為0Select

"abc"+"xyz";--0,0+0=07.1.4【實訓7-3】使用內(nèi)置函數(shù)(續(xù))--加上50天--減去500小4.日期和時間函數(shù)對日期、時間以及日期時間進行操作Select

adddate(‘2020-01-01’,interval

50

day);Select

subdate(‘2020-01-01’,interval

500

hour);時5.系統(tǒng)函數(shù)Insert

into

shop_province

values

(null,"XX省");Select

last_insert_id();

--返回新插入行的主鍵值Delete

from

shop_province

where

id_shop_province>5;Select

row_count();

--返回實際刪除的行數(shù)6.轉(zhuǎn)換函數(shù)在不同類型之間轉(zhuǎn)換Select

cast("1.234"

as

decimal(5,2));Select

convert("1.234",

decimal(5,2));7.1.4【實訓7-3】使用內(nèi)置函數(shù)(續(xù))6.轉(zhuǎn)換函數(shù)(續(xù))日期轉(zhuǎn)換為字符串date_format(date,

format)例如下述代碼Select

date_format(now(),

"%Y-%m-%d

%H:%i:%s");

--

2022-11-08

13:29:41字符串轉(zhuǎn)換為日期str_to_date(date,

format)通常情況下,字符串的日期時間可以直接用在insert和update語句中但是如果需要對得到明確的日期時間值,就需要轉(zhuǎn)換。例如下述代碼Select

str_to_date(‘2022-11-08

13:29:41’,‘%Y-%m-%d

%H:%i:%s’);--返回的是日期時間類型目錄任務(wù)2存儲函數(shù)任務(wù)1學習MySQL編程任務(wù)2存儲函數(shù)7.2.1存儲程序7.2.2【實訓7-5】存儲函數(shù)7.2.3【實訓7-6】管理存儲函數(shù)任務(wù)3使用存儲過程任務(wù)4使用觸發(fā)器任務(wù)5了解事務(wù)和鎖7.2.1存儲程序在學習存儲函數(shù)之前,先了解一下存儲程序的概念存儲程序(Stored

programs)

是存儲在數(shù)據(jù)庫中的一段程序,由單行語句或多行語句組成,并給予一個命名,通過該名字來運行或管理這些語句。MySQL的存儲程序有下述4種

存儲函數(shù)和存儲函數(shù)又稱為存儲例程(Stored

routine),僅僅是因為在數(shù)據(jù)庫備份中有一個選薦是備份存儲函數(shù)和存儲函數(shù)的,所以為其命名了一個名稱存儲例程存儲函數(shù)(Stored

function):本節(jié)講解存儲過程(Stored

procedure):下節(jié)講解觸發(fā)器(Trigger):再下一節(jié)講解事件(Event):項目11講解存儲程序{}存儲例程(Stored

routine)存儲程序概述4種存儲程序簡介存儲函數(shù)它返回一個計算結(jié)果,該結(jié)果可以用在表達式里(例如Select語句中的計算列)就像大多數(shù)語言中的函數(shù)一樣存儲過程它不直接返回結(jié)果,但可以用來完成一般的運算或是用Select語句生成一個結(jié)果集并傳遞回調(diào)用方它被call命令調(diào)用觸發(fā)器它與數(shù)據(jù)表相關(guān)聯(lián),不能被直接運行它是在該表執(zhí)行Insert、Delete或Update語句時觸發(fā)它的執(zhí)行事件它也不能被直接運行,而是根據(jù)設(shè)置的時間,在設(shè)置的預定時刻自動執(zhí)行存儲程序的優(yōu)點

存儲程序(特別是存儲例程和觸發(fā)器)具有如下優(yōu)點,曾經(jīng)受到廣泛應(yīng)用,有些項目甚至將所有的業(yè)務(wù)邏輯都寫在各種存儲程序中。

編譯后執(zhí)行:存儲程序經(jīng)過編譯之后會比單獨的SQL語句一條一條執(zhí)行要快,可以將編譯后的存儲程序緩存起來,從而提高系統(tǒng)性能。減少網(wǎng)絡(luò)傳輸:存儲程序保存在MySQL服務(wù)器中,距離數(shù)據(jù)最近,可以減少網(wǎng)絡(luò)傳輸,從而提高效率。

代碼復用:存儲程序被創(chuàng)建后,可以被不同的進程甚至是不同的語言調(diào)用,避免開發(fā)人員編寫相同的SQL語句,從而提高開發(fā)效率。流程控制:可以使用流程程控語句實現(xiàn)復雜的判斷和運算,編寫比較通用的存儲程序,從而提高靈活性。

隨著新技術(shù)的出現(xiàn),存儲程序的優(yōu)勢正在逐漸喪失,而缺點卻變得日益突出,主要是開發(fā)和調(diào)試困難、移植性差、不適應(yīng)新技術(shù)的應(yīng)用。因此,存儲程序已被許多公司限制使用。語句塊和語句分隔符從語法格式來說,存儲程序有兩種(以存儲程序為例)多條語句需要用begin和end將多條語句括起來,成為一個語句塊上述代碼出現(xiàn)一個問題,就是語句塊內(nèi)和語句塊外的行末分號有不同的作用,需要區(qū)分它們?yōu)榱藚^(qū)分語句塊內(nèi)和語句塊外的行末分號,MySQL特地提供一條命令,用于重新設(shè)定行末分隔符這條命令不能以分號結(jié)束,甚至行末不能加注釋(加行末注釋,有可能引起出錯)單語句存儲程序的語法格式Create

procedure存儲過程名(參數(shù))

[存儲過程特征]一條語句;多語句存儲程序的語法格式Delimiter

%%Create

procedure存儲過程名(參數(shù))

[存儲過程特征]begin第一條語句;……第n條語句;--這是語句塊內(nèi)的行末分號end;--這是語句塊外的行末分號這段代碼有問題!語句塊和語句分隔符(續(xù))因此,多語句存儲程序的正確的語法格式如下(以存儲程序為例)Delimiter

%%Create

procedure存儲過程名(參數(shù))

[存儲過程特征]begin第1條語句;第2條語句;……第n條語句;

end%%Delimiter

;紅框內(nèi)是一條語句(創(chuàng)建存儲程序,共8行),%%是這條語句的分隔符(標記語句結(jié)束)藍框內(nèi)是語句塊,每行都要用分號結(jié)束7.2.2【實訓7-5】存儲函數(shù)創(chuàng)建存儲函數(shù)的語法格式如下Create

function存儲函數(shù)名稱(參數(shù)列表)returns返回值類型[存儲函數(shù)特征]存儲函數(shù)體return返回值函數(shù)名通常加上前綴f_,避免與關(guān)鍵字沖突每一個參數(shù)都要指定數(shù)據(jù)類型參數(shù)列表后是“returns返回值類型”return動詞的單數(shù)形式,詞尾加s,主語是函數(shù)名,是單數(shù)的用于說明函數(shù)的返回值類型在函數(shù)體中必須有至少一條return語句return動詞的原型,無主句的動詞用動詞原型用于實際返回函數(shù)的值存儲函數(shù)特征在后面講解【實訓7-5】微課:7-1存儲函數(shù)1.單語句的存儲函數(shù)單語句的存儲函數(shù)的語法格式比較簡單下述語句用于創(chuàng)建存儲函數(shù)f_add()Create

function

f_add(_a

int,

_b

int)returns

int

no

sqlreturn

_a+_b;--函數(shù)體只有一行語句其中,no

sql是存儲函數(shù)特征,它的含義是這個存儲函數(shù)不包含SQL語句下述語句使用這個存儲函數(shù)Select

f_add(3,5);--使用存儲函數(shù)1.單語句的存儲函數(shù)(續(xù))單語句的存儲函數(shù)的函數(shù)體也可以是單條SQL語句例如下述代碼返回Select的查詢結(jié)果Create

function

f_get_total()returns

float

reads

sql

datareturn

(Select

sum(col_ammount)

from

shop_order_head);其中,reads

sql

data是存儲函數(shù)特征,含義是這個存儲函數(shù)里有讀數(shù)據(jù)的SQL語句return語句中的Select語句要用圓括號括起來,并且只能返回一個值(單行單列)下述語句使用這個存儲函數(shù)Select

f_get_total();--使用存儲函數(shù)2.多行語句的存儲函數(shù)如果存儲函數(shù)體有多行語句用begin和end關(guān)鍵字將多條語句括起來用Delimiter指定新的分隔符例如下述代碼定義了一個存儲函數(shù),它返回指定客戶(主鍵)的訂單數(shù)和購買商品數(shù),并將結(jié)果作為一個字符串返回Delimiter

%%Create

function

f_get_count(_id

int)

returns

varchar(20)

reads

sql

databegindeclare

var_order_count

int;--訂單數(shù)量declare

var_goods_count

int;--購買商品件數(shù)select

count(*)

into

var_order_count

from

shop_order_headwhere

id_shop_customer=_id

and

col_status>0;--查詢訂單數(shù)量select

sum(col_quantity)

into

var_goods_countfrom

shop_order_line

inner

join

shop_order_headon

shop_order_line.id_shop_order_head

=

shop_order_head.id_shop_order_headwhere

shop_order_head.id_shop_customer=_id

and

col_status>0;--查詢購買商品件數(shù)return

concat("(",

var_goods_count,

"/",

var_order_count,

")");end%%Delimiter

;定義新的分隔符使用新的分隔符恢復默認分隔符{塊中的分號是存儲過程內(nèi)部的分隔符號Select

f_get_count(2);--使用存儲函數(shù)7.2.3【實訓7-6】管理存儲函數(shù)

存儲函數(shù)是一個數(shù)據(jù)庫對象,它與表和視圖一樣,保存在數(shù)據(jù)庫中,可以創(chuàng)建、修改和丟棄,因此稱為“存儲函數(shù)”所有數(shù)據(jù)庫對象用下述語句創(chuàng)建:用Create

語句變更:用Alter

語句丟棄:用Drop

語句列出:用Show

語句1.列出存儲函數(shù)列出數(shù)據(jù)庫eshop中的所有存儲函數(shù)2.查看存儲函數(shù)的定義查看存儲函數(shù)f_get_count的定義。Show

create

function

f_get_count;3.丟棄存儲函數(shù)丟棄存儲函數(shù)Show

function

status

where

db

=

"eshop";Drop

function

[if

exists]存儲函數(shù)名;

加上if

exists后,可以保證即使存儲函數(shù)不存在也不會出錯【實訓7-6】7.2.3【實訓7-6】管理存儲函數(shù)(續(xù))4.修改存儲函數(shù)不能修改存儲函數(shù)的定義。如果要修改存儲函數(shù)的定義,要先刪除,后重新創(chuàng)建??梢孕薷拇鎯瘮?shù)的函數(shù)特征,語法格式如下。Alter

function存儲函數(shù)名存儲函數(shù)特征;創(chuàng)建存儲函數(shù)時可以指定函數(shù)特征,創(chuàng)建存儲函數(shù)后,還能用Alter修改其函數(shù)特征。deterministic或not

deterministic:前者指明執(zhí)行結(jié)果是確定的,相同的參數(shù)必定得到相同的結(jié)果。后者指明執(zhí)行結(jié)果是不確定的,例如含有日期時間函數(shù)或隨機數(shù)函數(shù)等,即使參數(shù)相同每次執(zhí)行都會有不同的結(jié)果no

sql:表示不包含sql語句contains

sql:表示包含sql語句,但不包含讀或?qū)憯?shù)據(jù)的語句reads

sql

data:表示包含讀(查詢)數(shù)據(jù)的語句modifies

sql

data:表示包含修改(增刪改)數(shù)據(jù)的語句sql

security{definer

|

invoker}:指明誰有權(quán)限執(zhí)行這個存儲函數(shù)comment"注釋內(nèi)容":指定注釋。例如下述語句修改存儲函數(shù)f_add()的函數(shù)特征為不包含SQL語句,任何人都可以執(zhí)行。function

f_add

no

sql,

sql

security

invoker;目錄任務(wù)3使用存儲過程任務(wù)1學習MySQL編程任務(wù)2存儲函數(shù)任務(wù)3使用存儲過程【實訓7-7】創(chuàng)建和使用存儲過程【實訓7-8】存儲過程的參數(shù)【實訓7-9】管理存儲過程任務(wù)4使用觸發(fā)器任務(wù)5了解事務(wù)和鎖7.3.1【實訓7-7】創(chuàng)建和使用存儲過程創(chuàng)建存儲過程的格式如下Create

procedure存儲過程名稱(參數(shù)列表)

[存儲過程特征]存儲過程體存儲過程名通常加上前綴p_,避免與關(guān)鍵字沖突存儲過程特征與存儲函數(shù)特征完全相同,見“7.2.3【實訓7-6】管理存儲函數(shù)”先舉個單語句的例子,下述代碼用于創(chuàng)建一個名為“p_goods_by_catgory”的存儲過程Create

procedure

p_goods_by_catgory(_id

int)Select

*

from

shop_goods

where

id_shop_category

=

_id;通過Call關(guān)鍵字調(diào)用這個存儲過程的語句如下Call

p_goods_by_catgory(2);執(zhí)行存儲過程就是執(zhí)行存儲過程體中的語句,在這個例子中,與直接使用Select語句的區(qū)別是商品類型是通過存儲過程的參數(shù)傳入的對調(diào)用者來說,不需要知道數(shù)據(jù)庫設(shè)計的細節(jié)就可以得到查詢的結(jié)果微課:7-2存儲過程【實訓7-7】7.3.1【實訓7-7】創(chuàng)建和使用存儲過程(續(xù))現(xiàn)在舉一個多行語句的例子,將上述代碼修改一下,加上if條件,成為多行語句Drop

procedure

if

exists

p_goods_by_catgory;--先丟棄它Delimiter

%%Create

procedure

p_goods_by_catgory(_id

int)beginif

(_id

>

0)

thenselect

*

from

shop_goods

where

id_shop_category

=

_id;elseselect

*

from

shop_goods;end

if;end%%Delimiter

;用大于0的參數(shù)調(diào)用,執(zhí)行查詢id為參數(shù)值的查詢Call

p_goods_by_catgory(2);用參數(shù)0調(diào)用,執(zhí)行沒有查詢條件的查詢Call

p_goods_by_catgory(0);判斷單行語句還是多行語句的原則單語句:存儲過程體內(nèi)沒有分號

多行語句:存儲過程體內(nèi)含有分號7.3.2【實訓7-8】存儲過程的參數(shù)存儲過程的參數(shù)無參有參輸入型:(默認)輸出型:用out關(guān)鍵字修飾輸入輸出型:用inout關(guān)鍵字修飾{{1.輸入型參數(shù)Create

procedure存儲過程名(變量名變量類型)存儲過程體2.輸出型參數(shù)Create

procedure存儲過程名(out

變量名變量類型)存儲過程體3.輸入輸出型參數(shù)Create

procedure存儲過程名(inout

變量名變量類型)存儲過程體【實訓7-8】輸出型參數(shù)1.輸入型參數(shù)見前面的講解2.輸出型參數(shù)下述存儲過程通過參數(shù)返回有效訂單的總金額Create

procedure

p_total_ammout(out

_ammount

float)select

sum(col_ammount)

into

_ammount

from

shop_order_headwhere

col_status>0;通過Call關(guān)鍵字調(diào)用這個存儲過程時通過一個用戶變量來接收輸出型參數(shù)的值調(diào)用后再處理這個變量Set

@ammount

=0;--必須要有一個變量用于接收輸出的數(shù)據(jù)

Call

p_total_ammout(@ammount

);Select

@ammount;--處理這個變量輸入輸出型參數(shù)3.輸入輸出型參數(shù)下述代碼的參數(shù)是輸入輸出型的它的輸入是客戶id值它的輸出是該客戶的有效訂單數(shù)輸入和輸出使用同一個變量_id。Create

procedure

p_total_quantity(inout

_id

int)select

count(*)

into

_id

from

shop_order_headwhere

id_shop_customer

=

_id

and

col_status>0;通過Call關(guān)鍵字調(diào)用這個存儲過程時通過一個用戶變量來接收輸出型參數(shù)的值同時這個用戶變量也用于傳入?yún)?shù)的值Set

@id=1;

--這個變量的值用于輸入

Call

p_total_quantity(@id);Select

@id;

--調(diào)用后同一個變量含有輸出值7.3.3【實訓7-9】管理存儲過程管理存儲過程與管理存儲函數(shù)完全相同,因為它們都屬于同一類“存儲例程”1.列出存儲過程列出數(shù)據(jù)庫eshop中的所有存儲過程Show

procedure

status

where

db

=

"eshop";2.查看存儲過程的定義查看存儲過程的定義。Show

create

procedure存儲過程名;3.丟棄存儲過程丟棄存儲過程Drop

procedure

[if

exists]存儲過程名;4.修改存儲過程不能修改存儲過程的定義。如果要修改存儲過程的定義,要先刪除,后重新創(chuàng)建??梢孕薷拇鎯^程的過程特征,語法格式如下。Alter

procedure存儲過程名存儲過程特征;【實訓7-9】目錄任務(wù)4使用觸發(fā)器任務(wù)1學習MySQL編程任務(wù)2存儲函數(shù)任務(wù)3使用存儲過程任務(wù)4使用觸發(fā)器觸發(fā)器概述【實訓7-10】before觸發(fā)器【實訓7-11】after觸發(fā)器觸發(fā)器中的新行和舊行【實訓7-12】管理觸發(fā)器數(shù)據(jù)庫對象總結(jié)任務(wù)5了解事務(wù)和鎖7.4.1觸發(fā)器概述實現(xiàn)復雜約束觸發(fā)器可以實現(xiàn)復雜的約束。例如觸發(fā)器可以引用其他表中的列,通過其他表中的數(shù)據(jù)來決定如何操作。比較數(shù)據(jù)狀態(tài)觸發(fā)器可以比較數(shù)據(jù)修改前后的差異,并根據(jù)這些差異采取不同的操作。方便統(tǒng)一管理觸發(fā)器集中保存在服務(wù)器端,方便統(tǒng)一管理和維護。維護困難觸發(fā)器是不能直接調(diào)用的,從應(yīng)用層面難以覺察底層觸發(fā)器的運行情況,會造成調(diào)試和排錯困難,有時會引起莫名其妙的后果。可移植性差不同的數(shù)據(jù)庫管理系統(tǒng)的觸發(fā)器語法差別較大,因此可移植性很差。占用資源觸發(fā)器占用服務(wù)器端較多的資源,對服務(wù)器造成較大的壓力,有時會嚴重影響服務(wù)器的性能觸發(fā)器不能被直接調(diào)用,觸發(fā)其執(zhí)行的事件主要有Insert、Update和Delete觸發(fā)器的優(yōu)點 ?

觸發(fā)器的缺點觸發(fā)器的功能十分強大,優(yōu)勢明顯,但缺點也非常突出,越來越多的公司開始限制觸發(fā)器的使用,而改用新的替代技術(shù)7.4.1觸發(fā)器概述(續(xù))觸發(fā)器的類型:根據(jù)被激活的時機的不同,分為兩種before觸發(fā)器:在觸發(fā)它的語句之前執(zhí)行,可以進行條件判斷,以決定是否執(zhí)行觸發(fā)它的語句after觸發(fā)器:在觸發(fā)它的語句之后執(zhí)行,可以在觸發(fā)語句執(zhí)行之后完成一個或更多的操作觸發(fā)條件:根據(jù)被激活的條件的不同,分為三種insert觸發(fā)器:在插入行的前或后時觸發(fā)觸發(fā)器的執(zhí)行update觸發(fā)器:在更新行的前或后時觸發(fā)觸發(fā)器的執(zhí)行delete觸發(fā)器:在刪除行的前或后時觸發(fā)觸發(fā)器的執(zhí)行因此,每張表最多定義6個不同的觸發(fā)器,對同一張表不能重復定義相同的觸發(fā)器insert觸發(fā)器update觸發(fā)器delete觸發(fā)器before觸發(fā)器√√√after觸發(fā)器√√√7.4.1觸發(fā)器概述(續(xù)二)創(chuàng)建觸發(fā)器Create

trigger觸發(fā)器名<before

|

after><insert

|

update

|

delete>

on表名for

each

row觸發(fā)器體為避免觸發(fā)器名與關(guān)鍵字沖突,觸發(fā)器名通常加上前綴t_觸發(fā)器類型的6種組合before

insertbefore

updatebefore

deleteafter

insertafter

updateafter

deleteon表名:每一張表最多可以定義6個觸發(fā)器,每種組合一個

for

each

row:影響多行時,每一行都會觸發(fā)一次,例如刪除了3行,就觸發(fā)3次delete觸發(fā)器7.4.2【實訓7-10】before觸發(fā)器先準備測試用的表tbl_personUse

test;Drop

table

if

exists

tbl_person;

--

丟棄表時,同時丟棄表上的觸發(fā)器Create

table

tbl_person(

--

創(chuàng)建表id

int(11)

not

null

primary

key

auto_increment,name

varchar(20),age

tinyint(4));采用觸發(fā)器技術(shù),檢查插入或更新數(shù)據(jù)時,年齡是否超出規(guī)定范圍當年齡小于0或大于120時設(shè)置出錯信息,并中止插入或更新數(shù)據(jù)否則正常執(zhí)行插入或更新數(shù)據(jù)【實訓7-10】微課:7-3觸發(fā)器7.4.2【實訓7-10】before觸發(fā)器(續(xù))編寫思路因為要決定是否允許插入/更新數(shù)據(jù),所以要用before觸發(fā)器因為要檢查插入和更新操作,所以要分別寫兩個觸發(fā)器(刪除操作與此無關(guān))兩個觸發(fā)器基本相同,僅僅是提示信息不同當new.age<0

or

new.age>120時設(shè)置出錯信息,并中止激發(fā)它的語句繼續(xù)執(zhí)行Delimiter

%%Create

trigger

t_before_insert_person

before

insert

on

tbl_person

for

each

rowbeginif

new.age<0

or

new.age>120

thensignal

sqlstate

"HY000"set

message_text="插入時,年齡范圍是0~120。";

end

if;end%%Create

trigger

t_before_update_person

before

update

on

tbl_person

for

each

rowbeginif

new.age<0

or

new.age>120

thensignal

sqlstate

"HY000"set

message_text="更新時,年齡范圍是0~120。";

end

if;end%%Delimiter

;signal

sqlstate

‘HY000’setmessage_text=“出錯信息";否則正常執(zhí)行插入或更新數(shù)據(jù)7.4.2【實訓7-10】before觸發(fā)器(續(xù)二)觸發(fā)器的效果

不論是通過命令行、圖形界面客戶端,還是其他任何途徑,進行插入或更新操作,都會觸發(fā)它的執(zhí)行,從而絕對保證不會出現(xiàn)非法的數(shù)據(jù)7.4.3【實訓7-11】after觸發(fā)器先準備測試用的表tbl_person(與前一實訓相同)Use

test;Drop

table

if

exists

tbl_person;Create

table

tbl_person(id

int(11)

not

null

primary

key

auto_increment,name

varchar(20),

age

tinyint(4));再準備一張表tbl_log,用于記錄用戶的操作Drop

table

if

exists

tbl_log;Create

table

tbl_log(id

int(11)

not

null

primary

key

auto_increment,log_text

varchar(500),

log_date

datetime);采用觸發(fā)器技術(shù),當插入或更新數(shù)據(jù)時,記錄用戶的操作,包括如下數(shù)據(jù)插入時,記錄插入的時間,插入的數(shù)據(jù)是什么更新時,記錄更新的時間,更新前的數(shù)據(jù)是什么樣的,更新后的數(shù)據(jù)是什么【實訓7-11】7.4.3【實訓7-11】after觸發(fā)器(續(xù))編寫思路因為要記錄操作的內(nèi)容,所以要用after觸發(fā)器因為要記錄插入和更新操作,所以要分別寫兩個觸發(fā)器(沒有要求記錄刪除操作)兩個觸發(fā)器基本相同,僅僅是記錄的內(nèi)容不同插入和更新操作激發(fā)它的執(zhí)行,是無條件的向日志表(

tbl_log)插入一行,包括操作的內(nèi)容的描述和操作發(fā)生的時間如果是插入記錄插入新行的姓名和年齡如果是更新記錄更新前的姓名和年齡,以及更新后的姓名和年齡Delimiter

%%Create

trigger

t_after_insert_person

after

insert

on

tbl_person

for

each

rowBeginInsert

into

tbl_log

values(null,concat("插入新行:id=",new.id,",姓名=",new.name,",年齡=",new.age),now());End%%Create

trigger

t_after_update_person

after

update

on

tbl_person

for

each

rowBegininsert

into

tbl_log

values(null,concat("更新行:id=",new.id,",姓名=",new.name,"(old=",old.name,"),年齡=",new.age,"(old=",old.age,")"),

now());End%%Delimiter

;7.4.3【實訓7-11】after觸發(fā)器(續(xù)二)觸發(fā)器的效果

不論是通過命令行、圖形界面客戶端,還是其他任何途徑,進行插入或更新操作,都會觸發(fā)它的執(zhí)行,從而絕對保證能夠記錄每一步操作,進行數(shù)據(jù)跟蹤

從記錄下來的操作日志中可以看到,“王五”的年齡一開始輸入的是22歲,后來在

12:09:22時被改為20歲的。如果有身份認證系統(tǒng),還可以記錄是誰修改的。如果還要記錄刪除操作,該如何做?7.4.4觸發(fā)器中的新行和舊行

在觸發(fā)器的觸發(fā)體中,有兩個特殊的對象new和old。對象new表示將要插入的新行,對象old表示將要刪除的舊行。在觸發(fā)器中通過new和old可以方便地獲取新行或舊行的列的值,并進行判斷或記錄。具體的代碼例子見前面講過的【實訓7-11】after觸發(fā)器

對于更新操作,可以理解為將舊行替換為新行,因此這時還可以比較新行和舊行的值,根據(jù)比較的結(jié)果進行操作。7.4.5【實訓7-12】管理觸發(fā)器管理觸發(fā)器與管理存儲例程比較相似1.列出觸發(fā)器Show

triggers;2.查看觸發(fā)器的定義Show

create

trigger觸發(fā)器名;3.丟棄觸發(fā)器Drop

trigger

[if

exists]觸發(fā)器名;4.不能修改觸發(fā)器不能修改觸發(fā)器的定義。如果要修改觸發(fā)器的定義,要先刪除,后重新創(chuàng)建觸發(fā)器沒有觸發(fā)器特征可以修改因此,觸發(fā)器沒有可以修改的內(nèi)容【實訓7-12】7.4.6數(shù)據(jù)庫對象總結(jié)存儲函數(shù)(Stored

function)存儲過程(Stored

procedure)觸發(fā)器(Trigger)視圖(View):項目6講解(視圖不是存儲程序){事件(Event):項目11講解數(shù)據(jù)庫對象}存儲例程(Stored

routine)表(Table)存儲對象{目錄任務(wù)5了解事務(wù)和鎖任務(wù)1學習MySQL編程任務(wù)2存儲函數(shù)任務(wù)3使用存儲過程任務(wù)4使用觸發(fā)器任務(wù)5了解事務(wù)和鎖事務(wù)【實訓7-13】體驗事務(wù)控制語句事務(wù)隔離和鎖機制7.5.1事務(wù)事務(wù)是什么?

事務(wù)是一個最小的、不可再分的工作單元,通常它對應(yīng)一個完整的業(yè)務(wù),其中包含了多個數(shù)據(jù)操縱(如insert、update、delete等)語句,共同完成這個業(yè)務(wù)。

下面用一個例子來說明事務(wù)的概念。首先創(chuàng)建一個簡單的銀行表(bank),其中有兩個賬戶A和B,分別向其中存入2

000元和3

000元。Create

table

bank(

--

說明概念的代碼,無須執(zhí)行account

varchar(20)

not

null

primary

key,

--

賬戶,主鍵ammount

decimal(10,2)

--

存款數(shù)目);Insert

into

bank

values("A",

2000);

--

賬戶A有存款2000元Insert

into

bank

values("B",

3000);

--

賬戶B有存款3000元存款總數(shù)是5

000元?,F(xiàn)在賬戶A想轉(zhuǎn)500元給賬戶B,該操作的代碼如下。Set

@transfer=500;

--轉(zhuǎn)賬的金額Update

bank

set

ammount=ammount-@transfer--轉(zhuǎn)賬第一步,從賬戶A中減去500元

where

account="A";--特定時間點Update

bank

set

ammount=ammount+@transfer--轉(zhuǎn)賬第二步,向賬戶B里加上500元

where

account="B";Select

*

from

bank;兩種可能的意外情況第一種情況在第一條Update語句執(zhí)行后,第二條Update語句還沒有執(zhí)行時,由于某種原因(例如停電)在這個特定的時間點出現(xiàn)了一個致命的錯誤,而使第二條Update語句無法執(zhí)行這時轉(zhuǎn)賬沒有完成,賬戶A的錢被扣除了,賬戶B的錢卻沒有增加這種情況出現(xiàn)的概率極其微小,但并不是不可能出現(xiàn),一旦出現(xiàn),將大大影響銀行的信譽第二種情況另一個用戶(例如銀行經(jīng)理)想要查詢銀行的存款總額,如果他的查詢操作是在第一條Update語句執(zhí)行完后的這個特定時間點進行的,那么查詢到的結(jié)果是存款總額為4

500元,而不是5

000元引起這個錯誤的原因是兩個用戶(轉(zhuǎn)賬用戶和銀行經(jīng)理用戶)的操作在時間上極其接近,而系統(tǒng)又沒有任何防范措施。

因此,一個完善的數(shù)據(jù)庫管理系統(tǒng)必須提供一個妥善的解決方法,以避免上述兩類事件對數(shù)據(jù)庫的影響,這個機制就是事務(wù)。

事務(wù)能夠保證上述兩條語句要么都執(zhí)行,要么都不執(zhí)行,并且一個事務(wù)的內(nèi)部處理不會對其他操作造成影響。事務(wù)的特性原子性(Atomicity)原子性是事務(wù)的最基本的特性,是指一個事務(wù)中的操作要么全部完成(提交),要么全部撤消(回滾)。一致性(Consistency)若數(shù)據(jù)庫只包含成功事務(wù)提交的結(jié)果,則稱數(shù)據(jù)庫處于一致性狀態(tài)。在事務(wù)的執(zhí)行過程中,數(shù)據(jù)庫會從一個一致性狀態(tài)(執(zhí)行前)變到另一個一致性狀態(tài)(執(zhí)行后),而不會處于中間狀態(tài)(不一致的狀態(tài))。隔離性(Isolation)并發(fā)執(zhí)行的事務(wù)之間不能相互干擾,并發(fā)事務(wù)間保持互斥的特性即為隔離性。持久性(Durability)事務(wù)一旦提交,事務(wù)對數(shù)據(jù)庫中數(shù)據(jù)的改變是永久的,接下來的其他操作或故障不應(yīng)該對其執(zhí)行結(jié)果有任何影響,這種特性稱為持久性。這4個特性也簡稱為ACID特性(

ACID是化學中“酸”的意思)事務(wù)的特性原子性(Atomicity)原子性是事務(wù)的最基本的特性,是指一個事務(wù)中的操作要么全部完成(提交),要么全部撤消(回滾)。一致性(Consistency)若數(shù)據(jù)庫只包含成功事務(wù)提交的結(jié)果,則稱數(shù)據(jù)庫處于一致性狀態(tài)。在事務(wù)的執(zhí)行過程中,數(shù)據(jù)庫會從一個一致性狀態(tài)(執(zhí)行前)變到另一個一致性狀態(tài)(執(zhí)行后),而不會處于中間狀態(tài)(不一致的狀態(tài))。隔離性(Isolation)并發(fā)執(zhí)行的事務(wù)之間不能相互干擾,并發(fā)事務(wù)間保持互斥的特性即為隔離性。持久性(Durability)事務(wù)一旦提交,事務(wù)對數(shù)據(jù)庫中數(shù)據(jù)的改變是永久的,接下來的其他操作或故障不應(yīng)該對其執(zhí)行結(jié)果有任何影響,這種特性稱為持久性。這4個特性也簡稱為ACID特性(

ACID是化學中“酸”的意思)并發(fā)控制并發(fā)是什么?如果只有一個用戶使用數(shù)據(jù)庫,那么就沒有并發(fā)的問題,就不需要考慮事務(wù)因為要同時為多個用戶提供服務(wù),所以就有可能有多個用戶同時訪問,這就是并發(fā)并發(fā)的概念

兩個或多個事務(wù)在同一時刻(時間間隔極其短暫)訪問同一個數(shù)據(jù)庫對象(例如同一行)的現(xiàn)象稱為并發(fā)(Concurrency)

并發(fā)控制(Concurrency

control)能夠確保當多個事務(wù)同時存取數(shù)據(jù)庫中同一數(shù)據(jù)時不破壞事務(wù)的隔離性、一致性并發(fā)與事務(wù)

事務(wù)是并發(fā)控制的基本單位,事務(wù)應(yīng)該保證下述兩類事件發(fā)生時,數(shù)據(jù)庫管理系統(tǒng)能夠正常運行事務(wù)在運行過程中被強行停止(例如停電、系統(tǒng)崩潰)。這時,數(shù)據(jù)庫管理系統(tǒng)必須保證被強行終止的事務(wù)對數(shù)據(jù)庫和其他事務(wù)沒有任何影響多個事務(wù)并發(fā)運行時,不同事務(wù)的操作交叉執(zhí)行。這時,數(shù)據(jù)庫管理系統(tǒng)必須保證多個事務(wù)交叉運行而不會產(chǎn)生相互影響事務(wù)控制語句

一個事務(wù)的開始、提交與回滾可以用SQL語句來實現(xiàn),在MySQL中,控制事務(wù)的語句主要有3條Begin(或Start

transaction):顯式地開啟一個事務(wù)

Commit:提交事務(wù),即提交事務(wù)的所有操作,具體來說就是將事務(wù)中所有對數(shù)據(jù)庫的更新寫到磁盤上的物理數(shù)據(jù)庫中去,事務(wù)正常結(jié)束

Rollback:回滾事務(wù),當事務(wù)運行的過程中發(fā)生了錯誤或故障,事務(wù)無法繼續(xù)執(zhí)行時,數(shù)據(jù)庫管理系統(tǒng)將事務(wù)中對數(shù)據(jù)庫的所有已執(zhí)行的操作全部撤銷,回滾到事務(wù)開始時

的狀態(tài)??梢院唵蔚乩斫鉃椤叭糠椿凇笔聞?wù)的開始與結(jié)束可以由用戶使用上述事務(wù)控制語句顯式控制如果用戶沒有顯式地定義事務(wù),數(shù)據(jù)庫管理系統(tǒng)將按一定的策略自動處理事務(wù)MySQL的默認事務(wù)處理策略是,將每一條SQL語句作為一個獨立的事務(wù),一旦執(zhí)行完成,立即提交。而使用Start

transaction語句則可以定義一個事務(wù),將多條SQL語句作為一個整體提交,或者在出現(xiàn)故障時回滾7.5.2【實訓7-13】體驗事務(wù)控制語句體驗事務(wù)的提交和回滾

前后兩次執(zhí)行代碼,修改倒數(shù)第2行代碼提交:Commit回滾:Rollback

比較結(jié)果的不同,回滾可以理解為“錯了,就全部反悔”

每次執(zhí)行代碼都會刪除數(shù)據(jù)表并重新創(chuàng)建,并初始化數(shù)據(jù),保證每次執(zhí)行時的初始數(shù)據(jù)完全相同。Use

test;--在測試數(shù)據(jù)庫test上進行演示,如果沒有這個數(shù)據(jù)庫,需要創(chuàng)建它

Drop

table

if

exists

bank;Create

table

bank(account

varchar(20)not

null

primary

key,--賬戶,主鍵

ammount

decimal(10,2)--存款數(shù)目);Insert

into

bank

values("A",2000);--賬戶A有存款2000元Insert

into

bank

values("B",3000);--賬戶B有存款3000元--存款總數(shù)是5000元?,F(xiàn)在賬戶A想轉(zhuǎn)500元給賬戶B,這時的操作應(yīng)該如下。SET

@transfer=500;Start

transaction;Update

bank

set

ammount=ammount-@transfer--轉(zhuǎn)賬第一步,從賬戶A中減去500元

where

account="A";Update

bank

set

ammount=ammount+@transfer--轉(zhuǎn)賬第二步,向賬戶B里加上500元where

account

=

"B";Commit;--把Commit改為Rollback,看看有什么區(qū)別

Select

*

from

bank;【實訓7-13】7.5.3事務(wù)隔離和鎖機制1、事務(wù)并發(fā)產(chǎn)生的問題

如果事務(wù)之間沒有隔離的話,當多個事務(wù)之間并發(fā)訪問時,可能出現(xiàn)臟讀、不可重復讀或幻讀等現(xiàn)象,其危害程度由高到低,如表7.10所示。2、鎖機制MySQL使用鎖機制來實現(xiàn)事務(wù)之間的隔離

例如一個事務(wù)對表或表中的某一行進行修改操作時,不允許另一個事務(wù)對同一張表或同一行進行操作,直到修改操作完成,第二個事務(wù)才能進行操作。這時第一個事務(wù)就要對表或表中的行進行鎖定,這就是鎖機制。MySQL的鎖有多種,例如共享(Share,S)鎖、排他(eXclusive,X)鎖、意向共享(Intent

Share,IS)鎖和意向排他(Intent

eXclusive,IX)鎖等,如表7.11所示。3、隔離級別MySQL提供了4種隔離級別來解決隔離問題統(tǒng)管理員只需要指定4種隔離級別中的某一種,MySQL會根據(jù)隔離的要系

求自動選擇合適的鎖機制,而不需要用戶進行太多的干預。

MySQL默認的隔離級別是“REPEATABLE-READ”(可重復讀),這個默認的隔離級別適合大多數(shù)的需求??梢杂孟率稣Z句查看隔離級別。Show

variables

like

"%isolation%";小結(jié)項目7數(shù)據(jù)庫編程任務(wù)1學習MySQL編程MySQL語言基礎(chǔ)MySQL流程控制內(nèi)置函數(shù)任務(wù)2存儲函數(shù)單語句存儲函數(shù)和多語句存儲函數(shù)任務(wù)3使用存儲過程存儲過程的參數(shù):無參數(shù),輸入型參數(shù),輸出型參數(shù),輸入輸出型參數(shù)任務(wù)4使用觸發(fā)器before觸發(fā)器和after觸發(fā)器的區(qū)別

觸發(fā)的條件:insert、update、delete任務(wù)5了解事務(wù)和鎖事務(wù)的提交和回滾,重點是理解,并不需要寫代碼看思維導圖,總結(jié)項目7謝謝大家!給授課教師的說明(閱畢刪除):本書提供的教案詳細說明了教學內(nèi)容的安排,請下載閱讀(掃碼教材封底二維碼,或訪問下載頁面/MySQLa/?p=2/links)上課時盡量少講理論,多做演示,可直接在“Jitor校驗器”的輔助下進行演示,與講授交叉進行,包括在教室上課。要求學生多動手操作,充分利用“Jitor校驗器”。項目8“在線商店”項目的開發(fā)體驗目錄任務(wù)1安裝和認識PHP任務(wù)1安裝和認識PHP安裝開發(fā)環(huán)境XAMPP【實訓8-1】PHP基本語法【實訓8-2】PHP數(shù)組(自學)任務(wù)2用PHP開發(fā)數(shù)據(jù)庫項目(自學)

任務(wù)3體驗“在線商店”應(yīng)用的開發(fā)過程8.1.1安裝開發(fā)環(huán)境XAMPP開發(fā)環(huán)境XAMPP簡介XAMPP

=

(Windows/Linux)+

Apache

+

MySQL

+

PHP

+

Perl本項目使用的精簡版是Apache

+PHP

+自己安裝的MySQL1、下載和安裝從本書附錄E提供的網(wǎng)盤地址下載精簡版的XAMPP

1.8.2,文件名xampp-x.zip,文件大小33MB解壓到任一盤符的根目錄下,注意必須解壓到根目錄下8.1.1安裝開發(fā)環(huán)境XAMPP(續(xù))2.啟動和停止XAMPP雙擊運行xampp-control.exe正常情況是自動啟動的可以從XAMPP控制面板停止Apache需要時再啟動它注:控制面板的版本是3.2.1,實際運行的XAMPP版本則是1.8.2注意觀察Apache的端口號圖8.1所示的是1443和8082前者是加密的HTTP端口號后者是普通的HTTP端口號因此,訪問這個網(wǎng)站的地址有兩個,這兩個地址訪問的是同一個網(wǎng)站,內(nèi)容完全相同8.1.1安裝開發(fā)環(huán)境XAMPP(續(xù))3.訪問xampp普通的HTTP地址(協(xié)議名為http)http://localhost:8082/加密的HTTP地址(協(xié)議名為https,其中s表示加密)https://localhost:1443/由于加密必需的證書沒有通過第三方的認證,這時反而會提示“不安全”上述兩個地址訪問的是相同的網(wǎng)站,首頁如右圖所示看到這個首頁,說明安裝成功8.1.2【實訓8-1】PHP基本語法1.HTML文件

HTML文件就是通常所說的網(wǎng)頁,是由超鏈接標記語言寫成的,它的擴展名是.html,它的基本元素是標簽。例如下述代碼。<html><head><meta

charset="UTF-8"><title>網(wǎng)頁標題</title></head><body>歡迎學習PHP語言。</body></html>

將上述內(nèi)容復制到記事本中,另存為page.html文件(位于htdocs下的test目錄中),在

“保存”或“另存為”時要將編碼改為UTF-8,否則會有中文亂碼?!緦嵱?-1】訪問HTML文件文件的路徑是:xampp安裝目錄下的htdocs/test/page.html訪問地址是:http://localhost:8082/

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論