MySQL基本操作整理(九)、MySQL中的變量、存儲過程、函數與流程控制結構

本文介紹MySQL數據庫中的變量、存儲過程、函數以及流程控制結構。這一塊是MySQL基礎中不會頻繁涉及的,但一旦使用就會極大提高工作效率的,特別是存儲過程函數

一、變量

MySQL中的變量主要分爲系統變量自定義變量,系統變量又分爲全局變量和會話變量,自定義變量分爲用戶變量和局部變量。

(一)系統變量

系統變量是由系統定義,不是用戶定義的,屬於服務器層面的變量。在系統變量中,又分爲全局變量和會話變量,全局變量需要添加global關鍵字,針對於所有會話(連接)有效,但不能跨重啓(重啓服務器後失效,可通過修改配置文件進行設置);會話變量需要添加session關鍵字,針對於當前會話(連接)有效;如果不寫標識,默認是會話變量。

系統變量的使用

  1. 查看所有系統變量
    show global |【session】variables;
  2. 查看滿足條件的部分系統變量
    show global |【session】 variables like ‘%char%’;
  3. 查看指定的系統變量的值
    select @@global. |【session.】系統變量名; (注意是兩個@,如查自動提交變量:select @@global.autocommit; )
  4. 爲某個系統變量賦值
    方式一:
    set global |【session】系統變量名=值; (如設置自動提交:set session autocommit = 1;)
    方式二:
    set @@global. |【session.】系統變量名=值;(如設置不自動提交:set @@session.autocommit = 0;)

記住上面的使用語法就可以了,下面是對全局變量和會話變量的分別介紹。

1.全局變量

作用域:針對於所有會話(連接)有效,但不能跨重啓。
使用

  1. 查看所有全局變量
    SHOW GLOBAL VARIABLES;
  2. 查看滿足條件的部分系統變量
    SHOW GLOBAL VARIABLES LIKE ‘%char%’;
  3. 查看指定的系統變量的值
    SELECT @@global.autocommit;
  4. 爲某個系統變量賦值
    方式一:
    SET @@global.autocommit=0;
    方式二:
    SET GLOBAL autocommit=0;

2.會話變量

作用域:針對於當前會話(連接)有效。
使用

  1. 查看所有會話變量
    SHOW SESSION VARIABLES;
  2. 查看滿足條件的部分會話變量
    SHOW SESSION VARIABLES LIKE ‘%char%’;
  3. 查看指定的會話變量的值
    SELECT @@session.autocommit; (其中session.可省略,即等效於SELECT @@autocommit;)
  4. 爲某個會話變量賦值
    方式一:
    SET @@session.autocommit=0;
    方式二:
    SET SESSION autocommit=0;

(二)自定義變量

自定義變量由用戶自定義創建,以滿足開發過程的使用。

1.用戶變量

用戶變量針對於當前會話(連接)有效,作用域同於會話變量。使用時和Java中使用變量一樣,分三步:聲明、賦值、使用(有查看變量值、比較、運算等)
(1)聲明(MySQL中的用戶變量聲明時必須初始化)。寫法如下,必須在變量名前加@符號,支持的賦值符號爲=和 :=,但若使用select則必須使用 := 的寫法(因爲分不清是否爲比較運算)。
SET @變量名=值;(由於等於號會有歧義,如將它與其他值進行比較,因此有下面 := 的寫法)
SET @變量名:=值;
SELECT @變量名:=值;
(2)賦值(或者叫更新變量值)
方式一:
SET @變量名=值;
SET @變量名:=值;
SELECT @變量名:=值;
方式二:
SELECT 字段 INTO @變量名 FROM 表;
(3)查看變量的值
SELECT @變量名;

2.局部變量

局部變量僅僅在定義它的begin end塊中有效,並且需要在 begin end中的第一句話開始定義。
(1)聲明局部變量
DECLARE 變量名 類型 【DEFAULT 值】;
(2)賦值
方式一:
SET 局部變量名=值;
SET 局部變量名:=值;
SELECT 局部變量名:=值;
方式二:
SELECT 字段 INTO 局部變量名 FROM 表;
(3)查看變量的值
SELECT 局部變量名;

案例:聲明兩個變量,求和並打印

#用戶變量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;

#局部變量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;
SELECT SUM;

用戶變量和局部變量的對比:

變量類型 作用域 定義位置 語法
用戶變量 當前會話 會話的任何地方 加@符號,不用指定類型
局部變量 定義它的BEGIN END中 BEGIN END的第一句話 一般不用加@,需要指定類型

二、存儲過程

MySQL中的存儲過程和函數類似於java中的方法,下面先介紹存儲過程。

1. 存儲過程介紹

含義:存儲過程是一組預先編譯好的SQL語句的集合,理解成批處理語句。
使用存儲過程的好處

  1. 提高代碼的重用性
  2. 簡化操作
  3. 減少了編譯次數並且減少了和數據庫服務器的連接次數,提高了效率

創建語法:

DELIMITER 結束標記
CREATE PROCEDURE 存儲過程名(參數列表)
BEGIN
	存儲過程體(一組合法的SQL語句)
END 結束標記

注意:
1、參數列表包含三部分:(參數模式 參數名 參數類型)
如:CREATE PROCEDURE myp1 (IN stuname VARCHAR(20)) …
參數模式:
in:該參數可以作爲輸入,也就是該參數需要調用方傳入值
out:該參數可以作爲輸出,也就是該參數可以作爲返回值
inout:該參數既可以作爲輸入又可以作爲輸出,也就是該參數既可以傳入值,又可以返回值

2、如果存儲過程體僅僅只有一句話,begin end可以省略
存儲過程體中的每條sql語句的結尾要求必須加分號。
存儲過程的結尾可以使用 delimiter 重新設置
語法:
delimiter 結束標記,如:delimiter $

調用語法:
CALL 存儲過程名(實參列表);

2. 存儲過程創建案例

案例1(空參列表的存儲過程):創建一個存儲過程,實現插入到admin表中五條記錄。

#創建
DELIMITER $
CREATE PROCEDURE myp1()
BEGIN
	INSERT INTO admin(username,`password`) 
	VALUES('john1','0000'),('lily','0000'),('rose','0000'),('jack','0000'),('tom','0000');
END $

#調用
CALL myp1()$
#查看
select * from admin$

案例2(創建帶in模式參數的存儲過程):創建存儲過程實現,根據女神名查詢對應的男神信息。

#創建
CREATE PROCEDURE myp2(IN beautyName VARCHAR(20))
BEGIN
	SELECT bo.*
	FROM boys bo
	RIGHT JOIN beauty b ON bo.id = b.boyfriend_id
	WHERE b.name = beautyName;
END $

#調用
CALL myp2('柳巖')$

案例3(創建帶兩個in模式參數的存儲過程):創建存儲過程實現,判斷用戶是否登錄成功,即用戶名和密碼是否匹配。

#創建
CREATE PROCEDURE myp3(IN username VARCHAR(20),IN PASSWORD VARCHAR(20))
BEGIN
	DECLARE result INT DEFAULT 0;#聲明並初始化	
	SELECT COUNT(*) INTO result#賦值
	FROM admin
	WHERE admin.username = username
	AND admin.password = PASSWORD;	
	SELECT IF(result>0,'成功','失敗') 狀態;#使用
END $

#調用
CALL myp3('張飛','8888')$

案例4(創建帶out模式參數的存儲過程):根據輸入的女神名,返回對應的男神名和魅力值

#創建
CREATE PROCEDURE myp4(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20),OUT usercp INT) 
BEGIN
	SELECT boys.boyname ,boys.usercp INTO boyname,usercp
	FROM boys 
	RIGHT JOIN
	beauty b ON b.boyfriend_id = boys.id
	WHERE b.name=beautyName ;	
END $

#調用
CALL myp4('小昭',@name,@cp)$
SELECT @name,@cp$

案例5(創建帶inout模式參數的存儲過程):傳入a和b兩個值,最終a和b都翻倍並返回

CREATE PROCEDURE myp5(INOUT a INT ,INOUT b INT)
BEGIN
	SET a=a*2;
	SET b=b*2;
END $

#調用
SET @m=10$ #需要先定義變量
SET @n=20$
CALL myp5(@m,@n)$
SELECT @m,@n$

3. 刪除存儲過程

語法:drop procedure 存儲過程名
存儲過程只能一次刪除一個,不支持同時刪除多個存儲過程。
DROP PROCEDURE p1;
DROP PROCEDURE p2,p3;#錯誤,不支持

4.查看存儲過程信息

語法:SHOW CREATE PROCEDURE myp1;
不能使用 DESC myp1;的方式

三、函數

1. 函數介紹

含義:函數和存儲過程一樣,是一組預先編譯好的SQL語句的集合,當然就具有以下的特點:
1、提高代碼的重用性
2、簡化操作
3、減少了編譯次數並且減少了和數據庫服務器的連接次數,提高了效率

函數和存儲過程的區別
存儲過程:可以有0個返回,也可以有多個返回,適合做批量插入、批量更新
函數:有且僅有1 個返回,適合做處理數據後返回一個結果

創建語法

CREATE FUNCTION 函數名(參數列表) RETURNS 返回類型
BEGIN
	函數體
END

注意
1、參數列表包含兩部分:參數名 參數類型
2、函數體:肯定會有return語句,如果沒有會報錯
如果return語句沒有放在函數體的最後不報錯,但不建議
3、函數體中僅有一句話,則可以省略begin end
4、使用 delimiter語句設置結束標記

調用語法
SELECT 函數名(參數列表)

2.函數創建案例

案例1(無參有返回):返回公司的員工個數

#創建
CREATE FUNCTION myf1() RETURNS INT
BEGIN
	DECLARE c INT DEFAULT 0;#定義局部變量
	SELECT COUNT(*) INTO c#賦值
	FROM employees;
	RETURN c;	
END $
#調用
SELECT myf1()$

案例2(有參有返回):根據員工名,返回它的工資

#創建
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
	SET @sal=0;#定義用戶變量 
	SELECT salary INTO @sal #賦值
	FROM employees
	WHERE last_name = empName;	
	RETURN @sal;
END $
#調用
SELECT myf2('k_ing') $

案例3(有參有返回):根據部門名,返回該部門的平均工資

#創建
CREATE FUNCTION myf3(deptName VARCHAR(20)) RETURNS DOUBLE
BEGIN
	DECLARE sal DOUBLE ;
	SELECT AVG(salary) INTO sal
	FROM employees e
	JOIN departments d ON e.department_id = d.department_id
	WHERE d.department_name = deptName;
	RETURN sal;
END $
#調用
SELECT myf3('IT')$

3. 查看函數

語法:SHOW CREATE FUNCTION myf3;

4. 刪除函數

語法:DROP FUNCTION myf3;

四、流程控制結構

mysql中的流程控制結構包括:順序結構、分支結構與循環結構。

順序結構:程序從上往下依次執行
分支結構:程序從兩條或多條路徑中選擇一條去執行
循環結構:程序在滿足一定條件的基礎上,重複執行一段代碼

順序結構很好理解,程序從上往下執行即可,下面主要介紹分支結構和循環結構。

(一)分支結構

1. if函數

功能:實現雙分支
語法:if(條件,值1,值2)
執行順序:
如果條件成立,則返回值1,否則返回值2

應用在任何地方(begin end中或外面)

2. case結構

語法:
情況1:類似於java中的switch語句,一般用於實現等值判斷

case 變量|表達式|字段
when 要判斷的值 then 返回的值1或語句1;
when 要判斷的值 then 返回的值2或語句2;

else 返回的值n或語句n;
end case

情況2:類似於java中的多重if語句,一般用於實現區間判斷
case
when 要判斷的條件1 then 返回的值1或語句1;
when 要判斷的條件2 then 返回的值2或語句2;

else 返回的值n或語句n;
end case

case作爲表達式的情況:
在這裏插入圖片描述
case作爲獨立語句的情況
在這裏插入圖片描述

特點:
1.可以作爲表達式,嵌套在其他語句中使用,可以放在任何地方,begin end 中或begin end的外面;可以作爲獨立的語句去使用,只能放在begin end中
2.如果when中的值滿足或條件成立,則執行對於功能的then後面的語句,並且結束case
如果都不滿足,則執行else中的語句或值
3.else可以省略,如果else省略了,並且所有when條件都不滿足,則返回null

3. if結構

功能:實現多重分支
語法:
if 條件1 then 語句1;
elseif 條件2 then 語句2;

【else 語句n;】
end if;
只能應用在begin end 中

案例1(使用存儲過程):創建存儲過程,根據傳入的成績,來顯示等級,如果成績爲90-100,顯示A,80-90,顯示B,60-80,顯示C,否則,顯示D

CREATE PROCEDURE test_case (IN score INT)
BEGIN
	CASE
	WHEN score>=90 AND score<=100 THEN SELECT 'A';
	WHEN score>=80 THEN SELECT 'B';
	WHEN score>=60 THEN SELECT 'C';
	ELSE SELECT 'D';
	END CASE; 
END $

案例2(使用函數):創建函數,實現傳入成績,如果成績>90,返回A,如果成績>80,返回B,如果成績>60,返回C,否則返回D

CREATE FUNCTION test_if(score INT) RETURNS CHAR
BEGIN
	IF score>=90 AND socre<=100 THEN RETURN 'A';
	ELSEIF score>=80 THEN RETURN 'B';
	ELSEIF score>=60 THEN RETURN 'C';
	ELSE RETURN 'D';
	END IF;		
END $

(二)循環結構

介紹:
MySQL中的循環結構分三類:while、loop、repeat

循環控制:
iterate 類似於 continue,繼續,結束本次循環,繼續下一次
leave 類似於 break,跳出,結束當前所在的循環

語法:
while:
【標籤:】while 循環條件 do
    循環體;
end while【 標籤】;

loop:
【標籤:】loop
循環體;
end loop 【標籤】;

repeat:
【標籤】repeat
循環體;
until 結束循環的條件
end repeat 【標籤】;

案例1(沒有添加循環控制語句):批量插入,根據次數插入到admin表中多條記錄

CREATE PROCEDURE pro_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	WHILE i<=insertCount DO
		INSERT INTO admin(username,`password`) VALUES(CONCAT('Rose',i),'666');
		SET i=i+1;
	END WHILE;	
END $

案例2(添加leave語句):批量插入,根據次數插入到admin表中多條記錄,如果次數>20則停止

CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	a:WHILE i<=insertCount DO
		INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');
		IF i>=20 THEN LEAVE a;
		END IF;
		SET i=i+1;
	END WHILE a;
END $

案例3(添加iterate語句):批量插入,根據次數插入到admin表中多條記錄,只插入偶數次

CREATE PROCEDURE test_while1(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 0;
	a:WHILE i<=insertCount DO
		SET i=i+1;
		IF MOD(i,2)!=0 THEN ITERATE a;
		END IF;		
		INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');		
	END WHILE a;
END $

案例4(流程控制經典案例):創建存儲過程,向 stringcontent 表中插入指定個數的隨機字符串,該表的結構如下:
CREATE TABLE stringcontent (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(20)
);

CREATE PROCEDURE test_randstr_insert(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
	DECLARE startIndex INT DEFAULT 1;
	DECLARE len INT DEFAULT 1;
	WHILE i<=insertCount DO
		SET len = FLOOR(RAND()*(20-startIndex+1) + 1);#產生一個隨機的整數,代表截取長度,1-(26-startIndex+1),此處定義的字符串最大長度爲20
		SET startIndex=FLOOR(RAND()*26+1);#產生一個隨機整數,代表起始索引1-26
		INSERT INTO stringcontent(content) VALUES(SUBSTR(str,startIndex,len));
		SET i = i+1;#循環變量更新
	END WHILE;
END $
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章