變量
系統變量
全局變量
作用域: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) $