【MySQL】MySQL概念解析(一)

一、MySQL變量

變量

系統變量
	全局變量
		作用域:MySQL服務器每次啓動將爲所有的全局變量賦初始值,所以全局變量作用範圍不能跨重啓
	會話變量
		作用域:針對於當前會話有效
	
自定義變量
	用戶變量
		作用域:針對於當前會話有效
	局部變量
		作用域:僅僅在定義它的begin end中有效。應用在begin end中的第一句話!!!

系統變量
【1】說明:變量由系統提供,不是用戶定義,屬於服務器層面
【2】語法
1、查看所有的系統變量
show global variables;
show session variables;

2、查看指定的某個系統變量的值
select @@global.系統變量名;
select @@session.系統變量名;

3、爲某個系統變量賦值
方式一:
set global 系統變量名 = 值
set session 系統變量名 = 值
方式二:
set @@global.系統變量名 = 值
set @@session.系統變量名 = 值

自定義變量
【1】說明:變量是用戶自定義的,不是系統的
使用步驟:聲明、賦值、使用(查看、比較、運算等)
【2】語法
用戶變量
1、聲明並初始化: 
set @用戶變量名=值
set @用戶變量名:=值
select @用戶變量名:=值

2、賦值:
方式一:
set @用戶變量名=值
set @用戶變量名:=值
select @用戶變量名:=值

方式二:
select 字段 into 用戶變量名 from 表

3、使用:
select @用戶變量名

局部變量
1、聲明並初始化:
declare 變量名 類型
declare 變量名 類型 default 值
2、賦值:
set 局部變量名=值
select 字段 into 局部變量名 from 表
3、使用:
select 局部變量名

二、存儲過程和函數

存儲過程和函數:類似於Java中的方法
好處:
1、提高代碼的重用性
2、簡化操作
3、減少了編譯次數並且減少了和數據庫服務器的連接次數,提高了效率

存儲過程
含義:一組預先編譯好的SQL語句的集合,理解成批處理語句
創建語法:
	create procedure 存儲過程名(參數列表)
	BEGIN
		存儲過程體(1組SQL語句)
	END
注意:
1、參數列表包含三部分:參數模式  參數名  參數類型
參數模式
IN:該參數可以作爲輸入,也就是該參數需要調用者傳入值
OUT:該參數可以作爲輸出,也就是該參數可以作爲返回值
INOUT:該參數即可以作爲輸入又可以輸出

2、如果存儲過程體僅僅只有一個SQL,BEGIN END可以省略
存儲過程體中的每條SQL語句的結尾要求必須加分號
存儲過程的結尾可以使用 delimiter 重新設置

語法:
delimiter 結束標記

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

示例:
注意:因爲在存儲過程中可以有多個SQL語句,多個SQL語句之間區別使用 ; 進行區分,所以和正常的SQL結束標記衝突了,我們需要將正常SQL語句中的結束標記替換了,比如換成 $,即使用 delimiter $ 命令即可替換,此後該會話所有的操作都是以 $ 爲結束符,例如: show table $ 、show databases $

delimiter $

【1】創建並調用存儲過程
CREATE PROCEDURE myp1()
BEGIN
    DROP TABLE IF EXISTS `boys`;
    DROP TABLE IF EXISTS `girls`;
    CREATE TABLE boys(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10) NOT NULL)CHARSET=utf8;
    CREATE TABLE girls(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(10) NOT NULL)CHARSET=utf8;
    INSERT INTO boys VALUES(NULL,'孫策'),(NULL,'周瑜'),(NULL,'劉備'),(NULL,'曹丕');
    INSERT INTO girls VALUES(NULL,'小喬'),(NULL,'大喬'),(NULL,'孫尚香'),(NULL,'甄姬');
END $

CALL myp1()$

---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp2(IN boyName VARCHAR(20),IN girlName VARCHAR(20))
BEGIN
	INSERT INTO boys VALUES(NULL,boyName);
	INSERT INTO girls VALUES(NULL,girlName);
END $

CALL myp2('呂布','貂蟬')$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp3(IN id INT,OUT boyName VARCHAR(20))
BEGIN
	SELECT b.name INTO boyName
	FROM boys b
	WHERE  b.id = id;
END $

CALL myp3(1,@resultName)$
SELECT @resultName$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp4(IN id INT,OUT id INT,OUT boyName VARCHAR(20))
BEGIN
	SELECT b.name,b.id INTO boyName,id
	FROM boys b
	WHERE  b.id = id;
END $

CALL myp4(1,@name,@id)$
SELECT @name,@id$
---------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE PROCEDURE myp5(INOUT a INT,INOUT b INT)
BEGIN
	set a = a * 2;
	set b = b * 2;
END $

set @m = 1 $
set @n = 2 $
call myp5(@m,@n) $
select @m,@n $

如果出現字符集錯誤,可以使用 set names gbk; 試試


【2】刪除存儲過程
語法:drop procedure 存儲過程名

【3】查看存儲過程的信息
語法:show create procedure 存儲過程名

【4】練習
1、創建存儲過程或函數,實現傳入一個日期,格式化成 xx年xx月xx日並返回
DROP PROCEDURE procedure_test_1 $
CREATE PROCEDURE procedure_test_1(IN date_time DATETIME,OUT str_datetime VARCHAR(50))
BEGIN
 SELECT DATE_FORMAT(date_time,"%y年%m月%d日") INTO str_datetime;
END $

CALL procedure_test_1(NOW(),@str_datetime) $
SELECT @str_datetime $;

2、創建存儲過程或函數,根據傳入的條目數和其實索引,查詢boys表的記錄
DROP PROCEDURE procedure_test_2 $
CREATE PROCEDURE procedure_test_2(IN size INT,IN startIndex INT)
BEGIN
 SELECT * from boys limit startIndex,size;
END $

CALL procedure_test_2(2,1) $


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

【2】創建語法
create function 函數名(參數列表) returns 返回類型
BEGIN
	函數體
END	

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

【3】調用語法
select 函數名(參數列表)$

【4】練習
1、無參有返回
drop function myf1 $
CREATE FUNCTION myf1() RETURNS INT
BEGIN
 DECLARE temp INT DEFAULT 0; # 定義局部變量
 SELECT COUNT(*) INTO temp
 FROM boys;
 RETURN temp;
END $
select myf1() $

2、有參有返回
DROP FUNCTION myf2 $
CREATE FUNCTION myf2(id INT) RETURNS VARCHAR(20)
BEGIN
 set @temp = 0; #定義用戶變量
 SELECT `name` INTO @temp
 FROM boys WHERE boys.id = id;
 RETURN @temp;
END $
SELECT myf2(2) $

【5】查看函數
show create function 函數名

【6】刪除函數
drop function 函數名

三、流程控制結構

流程控制結構

順序結構:程序從上往下依次執行
分支結構:程序選擇某一條路徑進行執行
循環結構:程序在滿足一定條件時,重複執行一段代碼


一、分支結構
1、if 函數
語法:
if (表達式1,表達式2,表達式3)
執行順序:如果表達式1成立,則 if 函數返回表達式2的值,否則返回表達式3的值

2、case結構
語法:
情況1:
case 變量|表達式|字段 
when 要判斷的值 then 返回的值1
when 要判斷的值 then 返回的值2
...
ELSE 要返回的值
END

情況2:
case 
when 要判斷的條件1 then 返回的值1
when 要判斷的條件2 then 返回的值2
...
ELSE 要返回的值
END

3、if 結構 (只能應用在 begin end中)
語法:
if 條件1 then 語句1;
elseif 條件2 then 語句2;
...
else 語句n;
end if;

二、循環結構
分類:
while、loop、repeat

循環控制:
iterate 類似於 continue
leave 類似於 break

1、while:先判斷後執行
語法:
【標籤:】while 循環條件 do
	循環體;
end while	【標籤】;

2、loop:沒有條件的死循環
【標籤:】loop
	循環體;
end loop 【標籤】;

3、repeat:先執行後判斷
語法:
【標籤:】repeat
	循環體;
until 結束循環的條件
end repeat【標籤】;	

4、練習
create procedure pro_while1(IN insertCount int)
begin
  declare i int default 1;
  while i <= insertCount do
	insert into boys values(null,concat("tom",i))
	set i = i + 1;
  end while;	
end $

call pro_while1(100) $

CREATE PROCEDURE pro_while2(IN insertCount INT)
BEGIN
  DECLARE i INT DEFAULT 1;
  a:WHILE i <= insertCount DO
	INSERT INTO boys VALUES(NULL,CONCAT("tom",i))
	IF i >= 20 THEN LEAVE a;
	END IF;
	SET i = i + 1;
  END WHILE a;	
END $

CALL pro_while2(100) $

CREATE PROCEDURE pro_while3(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 boys VALUES(NULL,CONCAT("tom",i))
	
  END WHILE a;	
END $

CALL pro_while3(100) $

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