MySQL函數以及循環結構


函數與存儲過程有什么區別

函數: 一組預先編譯號的sql語句的集合,理解成批處理語句

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

區別:

存儲過程:可以有0個返回,也可以有多個返回 ,(批量插入,批量更新)

函數:有且僅有一個返回 (適合做處理數據后返回一個結果)

  1. 創建語法:
    • create function 函數名(參數列表) returns 返回類型
    • begin
    • 函數體
    • end    
  2. 函數體:肯定會有return語句,如果沒有會報錯,如果return語句沒有放在函數體的最后也不會報錯,但不建議,建議return 值放到最后
  3. 函數體中僅有一句話的時候,則可以省略begin end
  4. 使用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 標簽;
  • 總結:
    •  

       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM