MySQL 數據庫(六)—— 數據庫編程:數據庫的變量、數據庫控制語句、數據庫函數、存儲過程、觸發器等

一、數據庫的變量

1、系統變量

(1)系統變量顧名思義就是系統提供的變量,屬於服務器層面上的,存放在數據庫服務端,用於設置整個數據庫的變量,如 autocommit。

如果是全局級別,則需要添加 GLOBAL,如果是會話級別,則添加 SESSION,如果不寫則默認 SESSION。

作用域:服務器每次啓動將爲所有的全局變量賦初始值,針對於所有的會話(連接)有效,但不能跨重啓(即修改過的系統變量在重啓會恢復默認值)。

(2)語法:
① 查看所有的系統變量

SHOW GLOBAL VARIABLES; -- 全局系統變量

② 查看滿足條件的部分系統變量

SHOW GLOBAL VARIABLES like '%char%';

③ 查看指定的某個系統變量的值

SELECT @@系統變量名;
SELECT @@GLOBAL.系統變量名;
-- eg:
SELECT @@GLOBAL.autocommit;

④ 設置系統變量名(修改系統變量)
系統變量會控制所有的用戶,一旦修改了系統變量,那麼所有的連接都將修改。
第一種方式:直接修改 這種修改方式只能修改當前連接客戶端的系統變量

SET 系統變量名 := 值;

第二種方式:這種修改能夠作用到整個數據庫服務端的系統變量,但使用這種方式修改, 當前連接的客戶端不會起作用,只有重新連接的客戶端纔會起作用。

SET @@GLOBAL.系統變量 = 值;
--eg:
SET @@GLOBAL.autocommit = 0;

2、會話變量

(1)當前連接的會話起作用。
作用域:僅僅針對於當前會話(連接)有效。
(2)語法
① 查看所有會話變量

SHOW  VARIABLES;
SHOW SESSION VARIABLES;

② 查看部分會話變量

SHOW  VARIABLES LIKE '%char%';
SHOW SESSION VARIABLES LIKE '%char%';

③ 查看指定的某個會話變量

SET @@會話變量名;
SET @@SESSION.會話變量;

④ 爲某個會話變量賦值(修改會話變量值)

SET @@會話變量 = 值;
SET @@SESSION.會話變量 = 值;
SET SESSION 會話變量名 = 值;

3、局部變量

(1)只能作用域區域的變量,作用域是 begin 和 end 區域之間,並且使用 declare 關鍵字進行定義
(2)步驟
① 聲明

DECLARE 變量名 類型;
DECLARE 變量名 類型; DEFAULT 值;
DECLARE i INT DEFAULT 0 ;

② 賦值(修改)
方式一

SET @局部變量名 = 值;
SET @局部變量名 := 值;
SELECT @局部變量名 := 值;

方式二

SELECT 字段 INTO @局部變量名 FROM 表;

③ 使用(查看)

SELECT @局部變量名;

4、自定義變量

(1)用戶自己定義的變量,不是系統的,針對於當前會話有效,等同於會話變量的作用域,但是可以應用在任何位置,begin和end裏面可以,外面也可以
(2)使用步驟
① 聲明並初始化

SET @用戶變量名 = 值;
SET @用戶變量名 := 值;
SELECT @用戶變量名 := 值;

因爲 " =" 容易有歧義,所以MySQL又推薦另一種寫法,":=" 。
② 賦值(修改用戶變量的值)
第一種:

SET @用戶變量名 = 值;
SET @用戶變量名 := 值;
SELECT @用戶變量名 := 值;

第二種:

SELECT 字段 INTO @用戶變量名 FROM 表;

③ 使用(查看用戶變量的值)

SELECT @用戶變量名;

二、控制語句——分支、循環

1、IF 分支

(1)語法:

IF 條件1 THEN
	執行語句1;
ELSE IF 條件2  THEN
	執行語句2;
...
ELSE
	執行語句n;
END IF;

(2)Demo:根據傳入的分數判斷成績等級

-- 根據傳入的分數判斷成績等級
delimiter &&
CREATE FUNCTION method5(score INT) RETURNS CHAR
BEGIN
	IF score >= 90 AND score <= 100 THEN
		RETURN 'A';
	ELSEIF score >= 80 THEN
		RETURN 'B';
	ELSEIF score >= 60 THEN
		RETURN 'C';
	ELSE
		RETURN 'D';
	END IF;
END
&&
delimiter ;
SELECT method5(85);

2、CASE 分支

(1)類似於java中的switch,一般用於實現等值判斷。
語法:

CASE 變量|表達式|字段
WHEN 值1 THEN 返回的值1或執行語句1;
WHEN 值2 THEN 返回的值2執行語句2;
...
ELSE 執行語句n;
END CASE;

是返回值的話不用加分號。

CASE 變量|表達式|字段
WHEN 值1 THEN 返回的值1
WHEN 值2 THEN 返回的值2
...
ELSE 執行語句n
END

(2)類似於java中的多重if語句,一般用於實現區間判斷。
語法:

CASE
WHEN 條件1 THEN 返回的值1執行語句1;
WHEN 條件2 THEN 返回的值2執行語句2;
...
ELSE 執行語句n;
END CASE;

注意:

  • 可以作爲表達式,嵌套在其他語句中,可以放在任何位置,BEGIN和END裏面和外面。可以作爲獨立的語句,只能放置BEGIN和END裏面使用。
  • 如上述語法中,如果是執行語句,滿足條件並執行對應語句之後就跳出整個結構,不滿足條件則繼續往下執行。
  • 如果WHEN中的值滿足或條件成立,則執行對應的THEN後面的語句,並且結束CASE,如果都不滿足,則執行ELSE中的語句。
  • ELSE可以省略,如果省略了,並且所有的WHEN的條件都不滿足,則返回NULL。

(3)Demo:根據傳入的分數判斷成績等級

-- 根據傳入的分數判斷成績等級
delimiter &&
CREATE PROCEDURE method4(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
&&
delimiter ;
CALL method4(85);

3、WHILE 循環

(1)分類
WHILE、LOOP、REPEAT

(2)循環控制
① leave: 離開循環,相當於java中的 break,結束整個循環
② iterate:持續迭代,相當於java中的 continue,結束本次循環繼續下次循環

(3)語法:
① WHILE 的語法

[標記:] WHILE 條件判斷 DO
	循環語句;
END WHILE [標記];

Demo:存儲過程實現100-500之間的累加

-- 存儲過程實現100-500之間的累加
delimiter &&
CREATE PROCEDURE method2()
BEGIN
	DECLARE sum INT DEFAULT 0;
	DECLARE i INT DEFAULT 100;
	WHILE i <= 500 DO
		SET sum := sum + i;
		SET i := i + 1;
	END WHILE;
	SELECT sum;
END
&&
delimiter ;
-- 查詢存儲過程
SHOW PROCEDURE STATUS;
-- 調用函數查看結果
CALL method2();

② LOOP的語法

[標記:] LOOP
	循環語句;
END LOOP [標記];

可以用來模擬簡單的死循環

③ REPEAT的語法

[標記:] REPEAT
	循環語句;
UNTIL 結束循環的條件
END REPEAT [標記];

Demo1:計算100以內的偶數和

-- 計算100以內的偶數和
-- 方法一
delimiter &&
CREATE FUNCTION method() RETURNS INT
BEGIN
	DECLARE sum INT DEFAULT 0;
	DECLARE i INT DEFAULT 0;
	-- WHILE 循環進行循環
	p1:WHILE i <= 100 DO
		-- IF 分支進行判斷
		IF i % 2 = 0 THEN
			SET sum := sum + i;
		END IF;
		SET i := i + 1;
	END WHILE p1;
	RETURN sum;
END;
&&
delimiter ;
-- 調用函數查看結果
SELECT method();

-- 方法二
delimiter &&
CREATE FUNCTION method1() RETURNS INT
BEGIN
	DECLARE i INT DEFAULT 0;
	DECLARE sum INT DEFAULT 0;
	p1:WHILE i < 100 DO
		SET sum := sum + i;
		if i % 2 <> 0 THEN
			-- 重新從p1出開始迭代
			ITERATE p1;
		END IF;
		SET sum := sum + i;
	END WHILE p1;
	RETURN sum;
END
&&
delimiter ;
-- 調用函數查看結果
SELECT method1();

Demo2:計算x的y次方

-- 計算x的y次方
delimiter &&
CREATE PROCEDURE method3()
BEGIN
	DECLARE x INT DEFAULT 2;
	DECLARE y INT DEFAULT 4;
	DECLARE i INT DEFAULT 0;
	DECLARE res DOUBLE DEFAULT 1.0;
	IF y > 0 THEN
		p1:WHILE i < y DO
			SET res = res * x;
			SET i = i + 1;
		END WHILE p1;
	END IF;

	IF y < 0 then
		set y = y * (-1);
		p2:WHILE i < y DO
			SET res = res * x;
			SET i = i + 1;
		END WHILE p2;
		set res = 1 / res;
		SELECT sum;
	END IF;

	IF y = 0 THEN
		SET res = 1;
	END IF;
	SELECT res;
END;
&&
delimiter ;
-- 調用函數查看結果
CALL method3();

三、數據庫的函數

1、基本函數

(1)常用方法
① 獲取字符的長度

char_length();

② 獲取字符串的字節數

length();

③ 截取函數:

left("你好世界",1); -- 從左邊開始截取多少個 
right();從右邊截取,同上 
mid();從中間截取

④ 時間函數

curdate(); -- 獲取當前日期:年月日 
curtime(); -- 獲取當前時間
now(); -- 獲取當前的日期 + 時間

⑤ 去空格

ltrim(); -- 去掉前面空格 
rtrim(); -- 去掉後面空格 
trim(); -- 去掉前後空格

⑥ 數學函數

pow(); -- 指數運算,如select POW(2,3); 
random(); -- 產生0-1的隨機小數

2、自定義函數

(1)自定義函數是可以實現一個特定功能的代碼塊
(2)語法
① 創建函數

CREATE FUNCTION 函數名([參數名 數據類型]) RETURNS 返回值數據類型 
BEGIN
	函數的功能語句;
	RETURN 返回值;
END;

注意:

  • 函數體肯定會有返回值,但沒有也不會報錯,如果 RETURN 語句沒有放在函數體的最後,也不會報錯,但是不建議這麼放置;
  • 如果函數體中只有一句話,可以省略 BEGIN 和 END;
  • delimiter 語句可以用於設置結束標記。

② 查詢函數

-- 查詢函數
SHOW FUNCTION  STATUS;
SHOW CREATE FUNCTION 函數名; -- 函數名後不加括號

③ 調用函數

SELECT 函數名(參數列表);

④ 刪除函數

DROP FUNCTION  函數名; -- 函數名後不加括號

Demo1:通過函數簡單計算

-- 計算1 + 2 方式1
delimiter &&
CREATE FUNCTION method() RETURNS INT
BEGIN
	DECLARE sum INT DEFAULT 0;
	DECLARE i INT DEFAULT 1;
	DECLARE j INT DEFAULT 2;
	SET sum := i + j;
	RETURN sum;
END;
&&
delimiter ;
-- 調用函數查看結果
SELECT method();

-- 計算1 + 2 方式2
delimiter &&
CREATE FUNCTION method(i INT,j INT) RETURNS INT
BEGIN
	DECLARE sum INT DEFAULT 0;
	SET sum := i + j;
	RETURN sum;
END;
&&
delimiter ;
-- 調用函數查看結果
SELECT method(1,2);

四、數據庫存儲過程 procedure

1、存儲過程概念

存儲過程類似於函數,是爲了實現特定功能的代碼,但是沒有返回值。

2、存儲過程的優點

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

3、存儲過程語法

(1)創建存儲過程

CREATE PROCEDURE 存儲過程名(參數模式 參數名 參數類型)
BEGIN
	存儲過程體(一組合法的SQL語句);
END

注意:

  • 參數模式:
    IN:表示該參數只能從存儲過程的外面傳到存儲過程的裏面使用;
    OUT:表示該參數只能從存儲過程的裏面傳到存儲過程的外面使用;
    INOUT:既可以從存儲過程的外面傳入到裏面使用,也可以從裏面傳入到外面使用。
  • 如果存儲過程體僅僅只有一句話,BEGIN和END可以省略。
  • 存儲過程體重的每條SQL語句的結尾必須要加分號";"。
  • 存儲過程的結尾可以使用 DELIMITER 重新設置,語法:
delimiter 結束標記
如
delimiter &&

(2)查詢存儲過程

查詢存儲過程 
SHOW PROCEDURE STATUS;
查看存儲過程信息
SHOW CREATE PROCDURE 存儲過程名;

(3)刪除存儲過程

DROP PROCEDURE 存儲過程名稱;

(4)調用存儲過程

CALL 存儲過程名(實參列表);

Demo1:存儲過程實現1 + 2的計算

-- 存儲過程實現1 + 2的計算
delimiter &&
CREATE PROCEDURE demo1()
BEGIN
	DECLARE i INT DEFAULT 1;
	DECLARE j INT DEFAULT 2;
	DECLARE sum INT DEFAULT 0;
	SET sum := i + j;
	SELECT sum;
END
&&
delimiter ;
-- 調用函數查看結果
CALL demo1();

Demo2:存儲過程實現100-500之間的累加

-- 存儲過程實現100-500之間的累加
delimiter &&
CREATE PROCEDURE demo2()
BEGIN
	DECLARE sum INT DEFAULT 0;
	DECLARE i INT DEFAULT 100;
	WHILE i <= 500 DO
		SET sum := sum + i;
		SET i := i + 1;
	END WHILE;
	SELECT sum;
END
&&
delimiter ;
-- 調用函數查看結果
CALL demo2();

Demo3:使用存儲過程向數據庫表中插入數據

-- 使用存儲過程向數據庫表中插入數據
delimiter &&
CREATE PROCEDURE demo3()
BEGIN
	DECLARE i int DEFAULT 7;
	p1:WHILE i <= 100 DO
		INSERT INTO student1 VALUES(i,'張三',"s007","id7");
		SET i = i + 1;
	END WHILE p1;
SELECT * FROM student1;
END;
&&
delimiter ;
CALL demo3();

Demo4:IN、OUT、INOUT的分析
在這裏插入圖片描述

Demo5:創建存儲過程實現傳入一個日期,格式化成yyyy年mm月dd日並返回

-- 創建存儲過程實現傳入一個日期,格式化成yyyy年mm月dd日並返回
delimiter &&
CREATE PROCEDURE datedemo(IN mydate DATETIME,OUT strDate VARCHAR(50))
BEGIN
	SELECT DATE_FORMAT(mydate,'%y年%m月%d日') INTO strDate;
END;
&&
delimiter ;
CALL datedemo(NOW(),@str);
SELECT @str;

五、數據庫觸發器 trigger

1、觸發器概念

不用主動調用,一旦滿足一定條件,會自動觸發。

2、觸發器語法

(1)創建觸發器

create trigger 觸發器名稱 觸發時機 觸發事件 on 表名 for each row
begin
	觸發器的代碼;
end

Demo:創建一個觸發器

-- 創建一個觸發器
CREATE TRIGGER tr AFTER INSERT ON orders FOR EACH ROW
BEGIN
	UPDATE product SET pnum = pnum - new.onum WHERE pid = old.pid;
END

(2)查詢觸發器

SHOW TRIGGERS;

(3)刪除觸發器

DROP TRIGGER 觸發器名字;

3、觸發器時機、事件

(1)觸發器時機:after,before
(2)觸發器事件:insert,delete,update
(3)new:如果是新增語句,使用new。
(4)old:如果是修改和刪除語句,使用old。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章