文章目錄
一、數據庫的變量
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。