函數與存儲過程有什么區別
函數: 一組預先編譯號的sql語句的集合,理解成批處理語句
- 提高代碼重用性
- 簡化操作
- 減少編譯次數和數據庫服務器的連接次數,提高效率
區別:
存儲過程:可以有0個返回,也可以有多個返回 ,(批量插入,批量更新)
函數:有且僅有一個返回 (適合做處理數據后返回一個結果)
- 創建語法:
- create function 函數名(參數列表) returns 返回類型
- begin
- 函數體
- end
- 函數體:肯定會有return語句,如果沒有會報錯,如果return語句沒有放在函數體的最后也不會報錯,但不建議,建議return 值放到最后
- 函數體中僅有一句話的時候,則可以省略begin end
- 使用delimiter 語句設置結束標記
二 調用語法
select 函數名(參數列表)
代碼演示
-
delimiter $$
create function myf2()
returns int
no sql
begin
declare c int default 0;
select count(*) into c from employees;
return c;
end $$
delimiter ;
select myf2()$ -
drop function myf3; 刪除函數
- 查看函數 show create function 函數名
show create function myf3;
-
delimiter $$
create function myf3(empName varchar(20))
returns double
reads sql data
begin
set @sal = 0; # 定義一個用戶變量
select salary into @sal
from employees
where last_name = empName;
return @sal;
end $$
delimiter ;
select myf3('Kochhar')$;
- 8.0以上mysql 創建函數錯誤
- [Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you might want to use the less safe log_bin_trust_function_creators variable)
- [Err] 1418-此函數中沒有聲明DETERMINISTIC,NO SQL或READS SQL DATA,只用聲明才會啟用二進制日志記錄(您可能想使用不太安全的log_bin_trust_function_creators變量)
- 解決辦法
- 第一種辦法,需要聲明DETERMINISTIC,NO SQL或READS SQL DATA的一種
- 第二種辦法,信任子程序的創建者,設置變量log_bin_trust_function_creators值為1
- -- 查看該參數,默認為0
- select @@log_bin_trust_function_creators;
- -- 設置為1
- set GLOBAL log_bin_trust_function_creators=1;
- 使用樣例
- 函數聲明NO SQL
- -- mysql中創建一個自定義函數
- delimiter $$
- create function fun_addnum()
- -- 注意是returns而不是return
- returns int
- NO SQL
- begin
- set @i=0;
- add_num:LOOP
- set @i=@i+1;
- -- leave用於跳出循環
- if @i=10 then leave add_num;
- -- iterate跳過后面語句進入下一循環
- elseif mod(@i,2)=0 then iterate add_num;
- end if;
- -- 結束循環
- end loop add_num;
- return @i;
- end $$
- delimiter ;
- select fun_addnum();
- 函數聲明DETERMINISTIC,表示該函數在每次為其參數調用相同值時都返回相同的結果值
- delimiter $$
- create function fun_hello(x int)
- returns int
- DETERMINISTIC
- comment '這是注釋'
- begin
- declare i int default 1;
- declare j int default 10;
- case x
- when i then set x=i;
- when j then set x=j;
- else set x=i+j;
- end CASE;
- return x;
- end $$
- delimiter ;
- select fun_hello(2);
- 設置變量log_bin_trust_function_creators的方式
- -- 設置為1,此時才可以使用 CONTAINS SQL,MODIFIES SQL DATA
- set GLOBAL log_bin_trust_function_creators=1;
- delimiter $$
- create function fun_temp()
- returns int
- -- READS SQL DATA
- MODIFIES SQL DATA
- begin
- declare cnt int default 0;
- repeat
- set cnt=cnt+1;
- until cnt=10 end repeat;
- return cnt;
- end $$
- delimiter ;
流程控制結構
順序結構:程序從上往下依次執行
分支結構: 程序從兩條或多條路徑中選擇一條去執行
循環結構:滿足一定條件基礎上。重復執行一段代碼
分支結構:
if函數: 實現簡單的雙分支
select if(B1,B2,B3)
如果B1成立,則if函數返回B2的值,否則返回B3的值 任何地方
- case 結構: 相當於switch 語句 一般實現等值判斷
-
語法:
case 變量|表達式|字段
when 判斷的值 then 返回值 |語句
when 判斷的值 then 返回值 |語句
when 判斷的值 then 返回值 |語句
else 要返會的值 n |語句
end
- 類似於java中多重if,區間判斷
-
語法:
case
when 條件 then 返回值 |語句
when 條件 then 返回值 |語句
when 條件 then 返回值 |語句
else 要返會的值 n |語句
end
- 特點:
- 可以作為表達式嵌套再其他語句中使用,也可以放在任何地方,begin end中或外面
- 也可以作為獨立的語句去使用,只能放在begin end中
- 實例:
-
delimiter $
create procedure testcase(in sal int)
begin
case
when sal>=90 then select 'A';
when sal>=80 then select 'B';
when sal>=70 then select 'C';
else select 'D';
end case;
end $
call testcase(82)$
-
- if結構,實現多重分支
- 語法:
- if 條件1 then 語句1
- else if 條件 then 語句2
- else 語句 n
- end if
- i應用在begin end中
- 實例:
-
delimiter $$
create function testif(socre int)
returns char
no sql
begin
if socre>=90 and socre <=100 then return 'A';
elseif socre>=80 then return 'B';
elseif socre>=70 then return 'C';
else return 'E';
end if;
end $$
delimiter ;
select testif(89)$;
-
- 語法:
- 循環結構
- 分類
- while
- loop
- repeat
- 循環控制
- iterate 類似於continue ,繼續,結束本次循環,繼續下一次
- leave 類似於break,跳出,結束循環
- while語法:
- while 條件 do
- 循環體;
- end while 標簽;
- 實例:
-
# 批量插入
delimiter $
create procedure pro_while1(in insertCount int)
begin
declare i int default 1;
a:while i<=insertCount do
insert into db01.tab1(id, age) values(i,i*10);
set i = i + 1;
end while a ;
end $
call pro_while1(7)$;
select * from tab1; -
delimiter $
create procedure pro_while2(in insertCount int)
begin
declare i int default 1;
a:while i<insertCount do
insert into tab1(id, age) values(i,i*10);
if i>=20 then leave a;
end if;
set i = i+1;
end while a;
end $
call pro_while2(21);
select * from tab1; -
delimiter $
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 tab1(id, age) values(i,i*10);
end while a;
end $
call pro_while3(30);
select * from tab1;
-
- loop語法
- loop
- 循環體
- end loop 標簽; 用來模擬死循環
- repeat語法:
- 標簽 repeat
- 循環體
- until 結束循環條件
- end repeat 標簽;
- 分類
- 總結:
-