MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

本篇文章進(jìn)行mysql的學(xué)習(xí),聊聊mysql中的流程控制和游標(biāo),希望對(duì)大家有所幫助。

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

學(xué)習(xí)或者了解過(guò)編程語(yǔ)言的都知道,任何一門編程語(yǔ)言都不可能只通過(guò)一兩句語(yǔ)句代碼完成。

流程控制語(yǔ)句的作用就是在程序運(yùn)行過(guò)程中控制語(yǔ)句的執(zhí)行順序,是我們完成復(fù)雜操作必不可少的一部分。

只要是執(zhí)行的程序,流程就分為三大類:

  • 順序結(jié)構(gòu):程序從上往下依次執(zhí)行
  • 分支結(jié)構(gòu):程序按條件進(jìn)行選擇執(zhí)行,從兩條或多條路徑中選擇一條執(zhí)行
  • 循環(huán)結(jié)構(gòu):程序滿足一定條件下,重復(fù)執(zhí)行一組語(yǔ)句

針對(duì)于MySQL 的流程控制語(yǔ)句主要有 3 類。注意:只能用于存儲(chǔ)程序。

  • 條件判斷語(yǔ)句:if 語(yǔ)句和 CASE 語(yǔ)句
  • 循環(huán)語(yǔ)句:LOOP、while 和 REPEAT 語(yǔ)句
  • 跳轉(zhuǎn)語(yǔ)句:ITERATE 和 LEAVE 語(yǔ)句

準(zhǔn)備工作:

創(chuàng)建數(shù)據(jù)庫(kù)以及兩張表,并插入數(shù)據(jù):

create?database?dbtest16; use?dbtest16;  create?table?employees? as? select?*?from?atguigudb.employees; create?table?departments as select?*?from?atguigudb.departments;  select?*?from?employees; select?*?from?departments;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)


分支結(jié)構(gòu)

分支,即二選一。在SQL中分支結(jié)構(gòu)主要有兩種展現(xiàn)形式:

  • IF
  • CASE

IF語(yǔ)句

  • IF 語(yǔ)句的語(yǔ)法結(jié)構(gòu)是:
IF?表達(dá)式1?THEN?操作1 [ELSEIF?表達(dá)式2?THEN?操作2]…… [ELSE?操作N] END?IF

根據(jù)表達(dá)式的結(jié)果為TRUE或FALSE執(zhí)行相應(yīng)的語(yǔ)句。這里“[]”中的內(nèi)容是可選的。

  • 特點(diǎn):① 不同的表達(dá)式對(duì)應(yīng)不同的操作 ② 使用在begin end中

舉例一:?jiǎn)闻袛?/p>

delimiter?// create?procedure?test_if() begin 		#?聲明局部變量 		declare?stu_name?varchar(15); 		if?stu_name?is?NULL 							then?select?'stu_name?is?null'; 		end?if; end// delimiter?; call?test_if();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例二:二選一

delimiter?// create?procedure?test_if2() begin 		declare?email?varchar(25); 		 		if?email?is?null 					then?select?'email?is?null'; 		else 					select?'email?is?not?null'; 		end?if; end// delimiter?; call?test_if2();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例三:多選一

delimiter?// create?procedure?test_if3() begin 		declare?age?int?default?20; 		 		if?age?>?40 					then?select?'中老年'; 		elseif?age?>?18 					then?select?'青壯年'; 		elseif?age?>?10 					then?select?'青少年'; 		else? 					select?'孩童'; 		end?if; end// delimiter?; call?test_if3();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

場(chǎng)景舉例一:聲明存儲(chǔ)過(guò)程“update_salary_by_eid1”,定義IN參數(shù)emp_id,輸入員工編號(hào)。判斷該員工薪資如果低于8000元并且入職時(shí)間超過(guò)5年,就漲薪500元;否則就不變。

delimiter?// create?procedure?update_salary_by_eid1(in?emp_id?int) begin ??#?聲明變量? 	declare?sal?double;??#?記錄員工工資 	declare?hiredate?date;??#?記錄入職日期 	#?查詢賦值 	select?salary,hire_date?into?sal,hiredate?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	if?sal??5? 				then?update?employees?set?salary?=?salary?+?500?where?employee_id?=?emp_id; 	end?if; end// delimiter;  set?@emp_id?=?104; #?更新前104號(hào)員工工資情況: select?salary,employee_id?from?employees?where?employee_id?=?@emp_id; #?更新工資: call?update_salary_by_eid1(@emp_id); #?再次查詢104號(hào)員工工資情況: select?salary,employee_id?from?employees?where?employee_id?=?@emp_id;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

場(chǎng)景舉例二:聲明存儲(chǔ)過(guò)程“update_salary_by_eid2”,定義IN參數(shù)emp_id,輸入員工編號(hào)。判斷該員工薪資如果低于9000元并且入職時(shí)間超過(guò)5年,就漲薪500元;否則就漲薪100元。

delimiter?// create?procedure?update_salary_by_eid2(in?emp_id?int) begin  ??#?聲明變量?  	declare?sal?double;??#?記錄員工工資 	declare?hiredate?date;??#?記錄入職日期 	#?查詢賦值 	select?salary,hire_date?into?sal,hiredate?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	if?sal??5? 				then?update?employees?set?salary?=?salary?+?500?where?employee_id?=?emp_id; 	else? 				update?employees?set?salary?=?salary?+?100?where?employee_id?=?emp_id; 	end?if;  end// delimiter; #?以103,104員工為例 #?更新前員工工資情況: select?salary,employee_id?from?employees?where?employee_id?in?(103,104); #?更新工資: call?update_salary_by_eid2(103); call?update_salary_by_eid2(104); #?再次查詢員工工資情況: select?salary,employee_id?from?employees?where?employee_id?in?(103,104);

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

場(chǎng)景舉例三:聲明存儲(chǔ)過(guò)程“update_salary_by_eid3”,定義IN參數(shù)emp_id,輸入員工編號(hào)。判斷該員工薪資如果低于9000元,就更新薪資為9000元; 薪資如果大于等于9000元且低于10000的,但是獎(jiǎng)金比例為NULL的,就更新獎(jiǎng)金比例為0.01;其他的漲薪100元。

delimiter?// create?procedure?update_salary_by_eid3(in?emp_id?int) begin ??#?聲明變量? 	declare?sal?double;??#?記錄員工工資 	declare?emp_commission_pct?double;??#?記錄獎(jiǎng)金比例 	#?查詢賦值 	select?salary,commission_pct?into?sal,emp_commission_pct?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	if?sal?<p><img src="https://img.php.cn/upload/image/883/381/664/1645617527844460.png" title="1645617527844460.png" alt="10.png"></p><p><img src="https://img.php.cn/upload/image/692/106/401/1645617530323910.png" title="1645617530323910.png" alt="11.png"></p><h3 data-id="heading-5">CASE語(yǔ)句</h3>
  • CASE 語(yǔ)句的語(yǔ)法結(jié)構(gòu)1:
#情況一:類似于switch CASE?表達(dá)式 WHEN?值1?THEN?結(jié)果1或語(yǔ)句1(如果是語(yǔ)句,需要加分號(hào))? WHEN?值2?THEN?結(jié)果2或語(yǔ)句2(如果是語(yǔ)句,需要加分號(hào)) ... ELSE?結(jié)果n或語(yǔ)句n(如果是語(yǔ)句,需要加分號(hào)) END?[case](如果是放在begin?end中需要加上case,如果放在select后面不需要)
  • CASE 語(yǔ)句的語(yǔ)法結(jié)構(gòu)2:
#情況二:類似于多重if CASE? WHEN?條件1?THEN?結(jié)果1或語(yǔ)句1(如果是語(yǔ)句,需要加分號(hào))? WHEN?條件2?THEN?結(jié)果2或語(yǔ)句2(如果是語(yǔ)句,需要加分號(hào)) ... ELSE?結(jié)果n或語(yǔ)句n(如果是語(yǔ)句,需要加分號(hào)) END?[case](如果是放在begin?end中需要加上case,如果放在select后面不需要)

舉例一:case … when … then …

delimiter?// create?procedure?test_case() begin 		declare?var?int?default?2; 		 		case?var 			????when?1?then?select?'var?=?1'; 					when?2?then?select?'var?=?2'; 					when?3?then?select?'var?=?3'; 					else?select?'other'; 		end?case; end?// delimiter?; call?test_case();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例二:case when … then …

delimiter?// create?procedure?test_case2() begin 		declare?var1?int?default?10; 		 		case??when?var1?&gt;=?100?then?select?'三位數(shù)'; 					when?var1?&gt;=10?then?select?'兩位數(shù)'; 					else?select?'個(gè)位數(shù)'; 		end?case; end?// delimiter?; call?test_case2();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

場(chǎng)景舉例一:– 聲明存儲(chǔ)過(guò)程“update_salary_by_eid4”,定義IN參數(shù)emp_id,輸入員工編號(hào)。 — 判斷該員工薪資如果低于9000元,就更新薪資為9000元; — 薪資大于等于9000元且低于10000的,但是獎(jiǎng)金比例為NULL的,就更新獎(jiǎng)金比例為0.01; — 其他的漲薪100元。

delimiter?// create?procedure?update_salary_by_eid4(in?emp_id?int) begin ??#?聲明變量? 	declare?sal?double;??#?記錄員工工資 	declare?emp_commission_pct?double;??#?記錄獎(jiǎng)金比例 	#?查詢賦值 	select?salary,commission_pct?into?sal,emp_commission_pct?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	case 	when?sal?<p><img src="https://img.php.cn/upload/image/504/278/295/1645617543487119.png" title="1645617543487119.png" alt="14.png"></p><p><img src="https://img.php.cn/upload/image/185/306/236/1645617546325789.png" title="1645617546325789.png" alt="15.png"></p><p>場(chǎng)景舉例二:-- 聲明存儲(chǔ)過(guò)程update_salary_by_eid5,定義IN參數(shù)emp_id,輸入員工編號(hào)。 -- 判斷該員工的入職年限,如果是0年,薪資漲50; -- 如果是1年,薪資漲100; -- 如果是2年,薪資漲200; -- 如果是3年,薪資漲300; -- 如果是4年,薪資漲400; -- 其他的漲薪500。</p><pre class="brush:sql;toolbar:false;">delimiter?// create?procedure?update_salary_by_eid5(in?emp_id?int) begin ??#?聲明變量? 	declare?sal?double;??#?記錄員工工資 	declare?hire_year?double;??#?記錄入職日期 	#?查詢賦值 	select?salary,round(datediff(now(),hire_date)/365)?into?sal,hire_year?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	case?hire_year 			when?0?then?update?employees?set?salary?=?salary?+?50?where?employee_id?=?emp_id; 			when?1?then?update?employees?set?salary?=?salary?+?100?where?employee_id?=?emp_id; 			when?2?then?update?employees?set?salary?=?salary?+?200?where?employee_id?=?emp_id; 			when?3?then?update?employees?set?salary?=?salary?+?300?where?employee_id?=?emp_id; 			when?4?then?update?employees?set?salary?=?salary?+?400?where?employee_id?=?emp_id; 			else?update?employees?set?salary?=?salary?+?500?where?employee_id?=?emp_id; 	end?case; end// delimiter; #?以107員工為例 #?更新前員工工資情況: select?salary,employee_id,hire_date?from?employees?where?employee_id?=?107; #?更新工資: call?update_salary_by_eid5(107); #?再次查詢員工工資情況: select?salary,employee_id,hire_date?from?employees?where?employee_id?=?107;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

#?針對(duì)場(chǎng)景二,此種寫法略顯不足,重復(fù)的書寫相同的更新語(yǔ)句, #?其實(shí)觀察下來(lái)也就金額不同,可以有改進(jìn)改進(jìn)如下: delimiter?// create?procedure?update_salary_by_eid6(in?emp_id?int) begin ??#?聲明變量? 	declare?sal?double;??#?記錄員工工資 	declare?hire_year?double;??#?記錄入職日期 	declare?add_sal?double;?#?保存更新的金額 	#?查詢賦值 	select?salary,round(datediff(now(),hire_date)/365)?into?sal,hire_year?from?employees? 	where?employee_id?=?emp_id; 	#?判斷條件并修改 	case?hire_year 			when?0?then?set?add_sal?=?50; 			when?1?then?set?add_sal?=?100; 			when?2?then?set?add_sal?=?200; 			when?3?then?set?add_sal?=?300; 			when?4?then?set?add_sal?=?400; 			else?set?add_sal?=?500; 	end?case; 	#?根據(jù)當(dāng)前add_sal值修改 	update?employees?set?salary?=?salary?+?add_sal?where?employee_id?=?emp_id; end// delimiter; #?以108員工為例 #?更新前員工工資情況: select?salary,employee_id,hire_date?from?employees?where?employee_id?=?108; #?更新工資: call?update_salary_by_eid5(108); #?再次查詢員工工資情況: select?salary,employee_id,hire_date?from?employees?where?employee_id?=?108;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

循環(huán)結(jié)構(gòu)

有時(shí)候我們需要重復(fù)的執(zhí)行某條語(yǔ)句,而借助循環(huán)結(jié)構(gòu)可以很好地實(shí)現(xiàn)。在MySQL中我們可以有三種方式實(shí)現(xiàn)循環(huán):

  • LOOP
  • WHILE
  • REPEAT

凡是循環(huán)結(jié)構(gòu)都遵循的四要素:

  • 1.初始化條件
  • 2.循環(huán)條件
  • 3.循環(huán)體
  • 4.迭代條件

LOOP語(yǔ)句

LOOP循環(huán)語(yǔ)句用來(lái)重復(fù)執(zhí)行某些語(yǔ)句。LOOP內(nèi)的語(yǔ)句一直重復(fù)執(zhí)行直到循環(huán)被退出(使用LEAVE子句),跳出循環(huán)過(guò)程。

LOOP語(yǔ)句的基本格式如下:

[loop_label:]?LOOP 	循環(huán)執(zhí)行的語(yǔ)句 END?LOOP?[loop_label]

其中,loop_label表示LOOP語(yǔ)句的標(biāo)注名稱,該參數(shù)可以省略。

舉例一:

delimiter?// create?procedure?test_loop() begin 		#?聲明變量 		declare?num?int?default?1; 		 		soberw:loop 				#?重新賦值 				set?num?=?num?+?1; 				if?num?&gt;=?10? 						then?leave?soberw; 				end?if; 		end?loop?soberw; 		 		#?查看num 		select?num; end?// delimiter?;  call?test_loop();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例二: — 當(dāng)市場(chǎng)環(huán)境變好時(shí),公司為了獎(jiǎng)勵(lì)大家,決定給大家漲工資。 — 聲明存儲(chǔ)過(guò)程“update_salary_loop()”,聲明OUT參數(shù)num,輸出循環(huán)次數(shù)。 — 存儲(chǔ)過(guò)程中實(shí)現(xiàn)循環(huán)給大家漲薪,薪資漲為原來(lái)的1.1倍。 — 直到全公司的平均薪資達(dá)到12000結(jié)束。 — 并統(tǒng)計(jì)循環(huán)次數(shù)。

delimiter?// create?procedure?update_salary_loop(out?num?int) begin ????#?聲明變量 		#?記錄保存平均薪資 		declare?avg_sal?double?default?0; 		#?記錄循環(huán)次數(shù) 		declare?count?int?default?0; 		#?獲取當(dāng)前平均薪資 		select?avg(salary)?into?avg_sal?from?employees; 		 		soberw:loop 				#?結(jié)束條件 				if?avg_sal?&gt;=?12000? 								then?leave?soberw; 						end?if; 				#?更新工資 				update?employees?set?salary?=?salary?*?1.1; 				#?保證當(dāng)前平均薪資為最新 				select?avg(salary)?into?avg_sal?from?employees; 				#?記錄次數(shù) 				set?count?=?count?+?1; 		end?loop?soberw; 		#?返回num 		set?num?=?count; end?// delimiter?;  call?update_salary_loop(@num); select?@num; select?avg(salary)?from?employees;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

WHILE語(yǔ)句

WHILE語(yǔ)句創(chuàng)建一個(gè)帶條件判斷的循環(huán)過(guò)程。WHILE在執(zhí)行語(yǔ)句執(zhí)行時(shí),先對(duì)指定的表達(dá)式進(jìn)行判斷,如果為真,就執(zhí)行循環(huán)內(nèi)的語(yǔ)句,否則退出循環(huán)。WHILE語(yǔ)句的基本格式如下:

[while_label:]?WHILE?循環(huán)條件??DO 	循環(huán)體 END?WHILE?[while_label];

while_label為WHILE語(yǔ)句的標(biāo)注名稱;如果循環(huán)條件結(jié)果為真,WHILE語(yǔ)句內(nèi)的語(yǔ)句或語(yǔ)句群被執(zhí)行,直至循環(huán)條件為假,退出循環(huán)。

舉例一:WHILE語(yǔ)句示例,i值小于10時(shí),將重復(fù)執(zhí)行循環(huán)過(guò)程

delimiter?// create?procedure?test_while() begin ????#?初始化條件 		declare?i?int?default?1; 		#循環(huán)條件 		while?i?<p><img src="https://img.php.cn/upload/image/656/908/601/1645617581540788.png" title="1645617581540788.png" alt="23.png"></p><p>舉例二: -- 市場(chǎng)環(huán)境不好時(shí),公司為了渡過(guò)難關(guān),決定暫時(shí)降低大家的薪資。 -- 聲明存儲(chǔ)過(guò)程“update_salary_while()”,聲明OUT參數(shù)num,輸出循環(huán)次數(shù)。 -- 存儲(chǔ)過(guò)程中實(shí)現(xiàn)循環(huán)給大家降薪,薪資降為原來(lái)的90%。 -- 直到全公司的平均薪資達(dá)到5000結(jié)束。 -- 并統(tǒng)計(jì)循環(huán)次數(shù)。</p><pre class="brush:sql;toolbar:false;">delimiter?// create?procedure?update_salary_while(out?num?int) begin ????#?聲明變量 		#?記錄保存平均薪資 		declare?avg_sal?double?default?0; 		#?記錄循環(huán)次數(shù) 		declare?count?int?default?0; 		#?獲取當(dāng)前平均薪資?初始化條件 		select?avg(salary)?into?avg_sal?from?employees; 		 		#循環(huán)條件 		soberw:while?avg_sal?&gt;?5000?do 				#?循環(huán)體		 				#?更新工資 				update?employees?set?salary?=?salary?*?0.9; 				#?記錄次數(shù) 				set?count?=?count?+?1; 				 				#?迭代條件 				#?保證當(dāng)前平均薪資為最新 				select?avg(salary)?into?avg_sal?from?employees; 				 		end?while?soberw; 		#?返回num 		set?num?=?count; end?// delimiter?;  call?update_salary_while(@num); select?@num; select?avg(salary)?from?employees;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

REPEAT語(yǔ)句

REPEAT語(yǔ)句創(chuàng)建一個(gè)帶條件判斷的循環(huán)過(guò)程。與WHILE循環(huán)不同的是,REPEAT 循環(huán)首先會(huì)執(zhí)行一次循環(huán),然后在 UNTIL 中進(jìn)行表達(dá)式的判斷,如果滿足條件就退出,即 END REPEAT;如果條件不滿足,則會(huì)就繼續(xù)執(zhí)行循環(huán),直到滿足退出條件為止。

REPEAT語(yǔ)句的基本格式如下:

[repeat_label:]?REPEAT     循環(huán)體的語(yǔ)句 UNTIL?結(jié)束循環(huán)的條件表達(dá)式 END?REPEAT?[repeat_label]

repeat_label為REPEAT語(yǔ)句的標(biāo)注名稱,該參數(shù)可以省略;REPEAT語(yǔ)句內(nèi)的語(yǔ)句或語(yǔ)句群被重復(fù),直至expr_condition為真。

舉例一:

DELIMITER?//  CREATE?PROCEDURE?test_repeat() BEGIN	 	DECLARE?i?INT?DEFAULT?0; 	 	REPEAT? 		SET?i?=?i?+?1; 	UNTIL?i?&gt;=?10 	END?REPEAT; 	 	SELECT?i; END?//  DELIMITER?;  call?test_repeat();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例二: — 當(dāng)市場(chǎng)環(huán)境變好時(shí),公司為了獎(jiǎng)勵(lì)大家,決定給大家漲工資。 — 聲明存儲(chǔ)過(guò)程“update_salary_repeat()”,聲明OUT參數(shù)num,輸出循環(huán)次數(shù)。 — 存儲(chǔ)過(guò)程中實(shí)現(xiàn)循環(huán)給大家漲薪,薪資漲為原來(lái)的1.15倍。 — 直到全公司的平均薪資達(dá)到13000結(jié)束。 — 并統(tǒng)計(jì)循環(huán)次數(shù)。

delimiter?// create?procedure?update_salary_repeat(out?num?int) begin 		#?聲明變量 		#?記錄保存平均薪資 		declare?avg_sal?double?default?0; 		#?記錄循環(huán)次數(shù) 		declare?count?int?default?0; 		#?獲取當(dāng)前平均薪資?初始化條件 		select?avg(salary)?into?avg_sal?from?employees; 		 		#循環(huán)條件 		soberw:repeat?? 				#?循環(huán)體		 				#?更新工資 				update?employees?set?salary?=?salary?*?1.15; 				#?記錄次數(shù) 				set?count?=?count?+?1; 				 				#?迭代條件 				#?保證當(dāng)前平均薪資為最新 				select?avg(salary)?into?avg_sal?from?employees; 				 		until?avg_sal?&gt;=?13000 		end?repeat?soberw; 		#?返回num 		set?num?=?count; end?// delimiter?;  call?update_salary_repeat(@num); select?@num; select?avg(salary)?from?employees;

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

對(duì)比三種循環(huán)結(jié)構(gòu):1、這三種循環(huán)都可以省略名稱,但如果循環(huán)中添加了循環(huán)控制語(yǔ)句(LEAVE或ITERATE)則必須添加名稱。 2、 LOOP:一般用于實(shí)現(xiàn)簡(jiǎn)單的”死”循環(huán) WHILE:先判斷后執(zhí)行 REPEAT:先執(zhí)行后判斷,無(wú)條件至少執(zhí)行一次

跳轉(zhuǎn)語(yǔ)句

跳轉(zhuǎn)語(yǔ)句可以協(xié)助我們更好的控制循環(huán)。

LEAVE語(yǔ)句

LEAVE語(yǔ)句:可以用在循環(huán)語(yǔ)句內(nèi),或者以 BEGIN 和 END 包裹起來(lái)的程序體內(nèi),表示跳出循環(huán)或者跳出程序體的操作。如果你有面向過(guò)程的編程語(yǔ)言的使用經(jīng)驗(yàn),你可以把 LEAVE 理解為 break

基本格式如下:

LEAVE?標(biāo)記名

其中,label參數(shù)表示循環(huán)的標(biāo)志。LEAVE和BEGIN … END或循環(huán)一起被使用。

舉例1:創(chuàng)建存儲(chǔ)過(guò)程 “l(fā)eave_begin()”,聲明INT類型的IN參數(shù)num。 給BEGIN…END加標(biāo)記名,并在BEGIN…END中使用IF語(yǔ)句判斷num參數(shù)的值。

  • 如果num
  • 如果num=1,則查詢“employees”表的平均薪資;
  • 如果num=2,則查詢“employees”表的最低薪資;
  • 如果num>2,則查詢“employees”表的最高薪資。

IF語(yǔ)句結(jié)束后查詢“employees”表的總?cè)藬?shù)。

delimiter?// create?procedure?leave_begin(in?num?int) soberw:begin 		if?num??2 				then?select?max(salary)?from?employees; 		end?if; 		select?count(1)?from?employees; end// delimiter?;  call?leave_begin(2); call?leave_begin(-1);

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

舉例2: — 當(dāng)市場(chǎng)環(huán)境不好時(shí),公司為了渡過(guò)難關(guān),決定暫時(shí)降低大家的薪資。 — 聲明存儲(chǔ)過(guò)程“l(fā)eave_while()”,聲明OUT參數(shù)num,輸出循環(huán)次數(shù), — 存儲(chǔ)過(guò)程中使用WHILE循環(huán)給大家降低薪資為原來(lái)薪資的90%, — 直到全公司的平均薪資小于等于10000, — 并統(tǒng)計(jì)循環(huán)次數(shù)。

delimiter// create?procedure?leave_while(out?num?int) begin 		declare?avg_sal?double; 		declare?count?int?default?0; 		 		select?avg(salary)?into?avg_sal?from?employees; 		soberw:while?true?do 		 				if(avg_sal?<p><img src="https://img.php.cn/upload/image/104/290/935/1645617615526003.png" title="1645617615526003.png" alt="31.png"></p><p><img src="https://img.php.cn/upload/image/253/645/607/1645617618221965.png" title="1645617618221965.png" alt="32.png"></p><h3 data-id="heading-12">ITERATE語(yǔ)句</h3><p>ITERATE語(yǔ)句:只能用在循環(huán)語(yǔ)句(LOOP、REPEAT和WHILE語(yǔ)句)內(nèi),表示重新開始循環(huán),將執(zhí)行順序轉(zhuǎn)到語(yǔ)句段開頭處。如果你有面向過(guò)程的編程語(yǔ)言的使用經(jīng)驗(yàn),你可以把 ITERATE 理解為 continue,意思為“再次循環(huán)”。</p><p>語(yǔ)句基本格式如下:</p><pre class="brush:sql;toolbar:false;">ITERATE?label

label參數(shù)表示循環(huán)的標(biāo)志。ITERATE語(yǔ)句必須跟在循環(huán)標(biāo)志前面。

舉例一:定義局部變量num,初始值為0。循環(huán)結(jié)構(gòu)中執(zhí)行num + 1操作。 — 如果num 15,則退出循環(huán)結(jié)構(gòu);

delimiter?// create?procedure?test_iterate() begin 		declare?num?int?default?0; 		soberw:loop 				set?num?=?num?+?1; 				if?num?15 					then?leave?soberw; 			??end?if; 		end?loop?soberw; 		 		select?num; end// delimiter?;  call?test_iterate();

MySQL學(xué)習(xí)之聊聊流程控制和游標(biāo)

游標(biāo)

雖然我們也可以通過(guò)篩選條件 WHERE 和 HAVING,或者是限定返回記錄的關(guān)鍵字 LIMIT 返回一條記錄,但是,卻無(wú)法在結(jié)果集中像指針一樣,向前定位一條記錄、向后定位一條記錄,或者是隨意定位到某一條記錄,并對(duì)記錄的數(shù)據(jù)進(jìn)行處理。

這個(gè)時(shí)候,就可以用到游標(biāo)。游標(biāo),提供了一種靈活的操作方式,讓我們能夠?qū)Y(jié)果集中的每一條記錄進(jìn)行定位,并對(duì)指向的記錄中的數(shù)據(jù)進(jìn)行操作的數(shù)據(jù)結(jié)構(gòu)游標(biāo)讓 SQL 這種面向集合的語(yǔ)言有了面向過(guò)程開發(fā)的能力。

在 SQL 中,游標(biāo)是一種臨時(shí)的數(shù)據(jù)庫(kù)對(duì)象,可以指向存儲(chǔ)在數(shù)據(jù)庫(kù)表中的數(shù)據(jù)行指針。這里游標(biāo)充當(dāng)了指針的作用,我們可以通過(guò)操作游標(biāo)來(lái)對(duì)數(shù)據(jù)行進(jìn)行操作。

MySQL中游標(biāo)可以在存儲(chǔ)過(guò)程和函數(shù)中使用。

游標(biāo)使用的步驟:

  • 1)聲明游標(biāo) ? DECLARE cursor_name CURSOR for select_statement;
  • 2)打開游標(biāo) ? OPEN cursor_name
  • 3)使用游標(biāo)(從游標(biāo)中獲取數(shù)據(jù)) ?FETCH cursor_name INTO var_name [, var_name] …
  • 4)關(guān)閉游標(biāo) ? CLOSE cursor_name

注意:游標(biāo)的查詢結(jié)果集中的字段數(shù),必須跟 INTO 后面的變量數(shù)一致,否則,在存儲(chǔ)過(guò)程執(zhí)行的時(shí)候,MySQL 會(huì)提示錯(cuò)誤。

有 OPEN 就會(huì)有 CLOSE,也就是打開和關(guān)閉游標(biāo)。當(dāng)我們使用完游標(biāo)后需要關(guān)閉掉該游標(biāo)。因?yàn)橛螛?biāo)會(huì)占用系統(tǒng)資源,如果不及時(shí)關(guān)閉,游標(biāo)會(huì)一直保持到存儲(chǔ)過(guò)程結(jié)束,影響系統(tǒng)運(yùn)行的效率。而關(guān)閉游標(biāo)的操作,會(huì)釋放游標(biāo)占用的系統(tǒng)資源。

舉例: — 創(chuàng)建存儲(chǔ)過(guò)程“get_count_by_limit_total_salary()”, — 聲明IN參數(shù) limit_total_salary,DOUBLE類型; — 聲明OUT參數(shù)total_count,INT類型。 — 函數(shù)的功能可以實(shí)現(xiàn)累加薪資最高的幾個(gè)員工的薪資值, — 直到薪資總和達(dá)到limit_total_salary參數(shù)的值, — 返回累加的人數(shù)給total_count。

delimiter?// create?procedure?get_count_by_limit_total_salary(in?limit_total_salary?double,out?total_count?int) begin ????#?保存薪資和 		declare?sum_sal?double?default?0; 		#?保存累加人數(shù) 		declare?count?int?default?0; 		#?定義單個(gè)工資 		declare?emp_salary?double?default?0; 		#?定義游標(biāo) 		declare?cursor_sal?cursor?for?select?salary?from?employees?order?by?salary?desc; 		#?打開游標(biāo) 		open?cursor_sal; 		#?使用游標(biāo) 		while?sum_sal?<p><img src="https://img.php.cn/upload/image/432/585/298/1645617628670189.png" title="1645617628670189.png" alt="34.png"></p><p>【相關(guān)推薦:<a href="https://www.php.cn/course/list/51.html" target="_blank" textvalue="mysql視頻教程">mysql視頻教程</a>】</p>

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊8 分享