MySQL儲存過程入門基礎
阿新 • • 發佈:2022-01-07
建立儲存過程無參語法:
delimiter //
create procedure 函式名()
begin
業務邏輯
end //
call 函式名() 通過函式名呼叫儲存過程
建立儲存過程有參與法:
delimiter //
create procedure 函式名(in 引數名 引數型別,out 引數名 引數型別)
begin
end //
call 函式名() 通過函式名呼叫儲存過程
引數詳解:
delimiter宣告結束符,使語句執行時遇到;不判斷為結束標識 in表示入參,只能是傳入引數時賦值,之後不可賦值; out 表示出參,只能是返回引數時賦值,之後不可賦值; inout 表示入參和出參都可以賦值;
變數詳解:
declare 變數名 varchar(32) default ‘var_value’ 設定預設值
set 變數名 = ‘a’ set給變數賦值
select s.name into 變數名 from sys_user where ID = 1; into給變數賦值
declare宣告變數為區域性變數,只作用於begin-end中;
set @name = ‘a’
@宣告變數為使用者變數,作用於當前會話(當前連線)
判斷語法:
if 變數名 > 1 then 判斷條件中只要不是else必須加then 業務邏輯... elseif 變數名 < 3 then 業務邏輯... else 業務邏輯... end if; 結束
迴圈語法1:
別名:loop
if 條件 then
業務邏輯...
iterate 別名; iterate表示繼續執行當前迴圈,相當於Java中的continue
end if;
leave 別名; leave表示跳出迴圈,如不寫則是死迴圈
end loop 別名;
迴圈語法2:
別名:repeat
until 條件 until表示迴圈直到條件不成立才繼續往下執行
業務邏輯...
end repeat 別名;
迴圈語法3:
別名:while
條件 do
業務邏輯...
end while 別名;
遊標:
遊標每次fetch指向的是一行資料的值,當fetch指向最後一行資料是再次fetch會報錯(no data錯誤)異常程式碼1329或 0200 解決方案:handler控制代碼捕獲異常 declare 布林變數 boolean default true 布林型別變數用作捕獲異常的判斷條件 declare 遊標名 cursor for 結果集 此時該遊標是沒有值的,結果集通過SQL查詢 declare continue handler for xxx set 布林變數 = false 建立handler控制代碼 捕獲xxx異常(此處xxx表示異常程式碼,一般no data異常捕獲常用not found,如:1329表示no data異常)一旦捕獲異常就將原有的布林變數改為false(continue修飾handler控制代碼時捕獲到異常繼續往下執行,exit修飾的handler控制代碼捕獲到異常時不繼續往下執行,直接停止儲存過程) open 遊標名 此時將結果集賦值給遊標 迴圈別名:loop fetch 遊標名 into 變數接收遍歷的值 這裡的變數順序要跟查詢結果集的SQL中的欄位順序、欄位型別一致 if 布林變數 then else leave 迴圈別名; end if; end loop 迴圈別名; close 遊標名 ;
注意:
在語法中,變數宣告->遊標宣告->handler控制代碼宣告必須按照此先後順序書寫,否則建立儲存過程出錯;
MySQL中的時間函式:
DATE_ADD(now(),INTERVAL 1 month) 表示獲取下個月的當前時間
LAST_DAY(DATE_ADD(now(),INTERVAL 1 month)) 表示獲取下個月的最後一天
YEAR(DATE_ADD(now(),INTERVAL 1 month)) 表示獲取該日期中的年份
MONTH(DATE_ADD(now(),INTERVAL 1 month)) 表示獲取該日期中的月份
DAYOFMONTH(DATE_ADD(now(),INTERVAL 1 month)) 表示獲取該日期中的日
根據日期動態建立表:
--建立結束識別符號
delimiter //
--建立函式
create procedure create_table()
begin
--建立區域性變數
declare table_year int ;
declare table_month int;
declare table_day int;
declare table_day_index int default 1;
declare table_day_str char(2);
declare table_month_str char(2);
declare table_name_str char(10);
--獲取下個月的年份
set table_year = YEAR(DATE_ADD(now(),INTERVAL 1 month));
--獲取下個月的月份
set table_month = MONTH(DATE_ADD(now(),INTERVAL 1 month));
--獲取下個月最後一天
set table_day = DAYOFMONTH(LAST_DAY(DATE_ADD(now(),INTERVAL 1 month)));
--判斷月份是否小於10,如成立,前面拼接'0',如不是不需要拼接
if table_month < 10 then
set table_month_str = concat('0',table_month);
else
set table_month_str = concat('',table_month);
end if;
--迴圈建立表,每月一號是固定的所以'1'為起始條件,下個月的最後一天為結束條件
while table_day_index <= table_day do
--判斷天是否小於10,如成立,前面拼接'0',如不是不拼接
if table_day_index < 10 then
set table_day_str = concat('0',table_day_index);
else
set table_day_str = concat('',table_day_index);
end if;
--拿到年、月、日之後拼接字串作為表名字尾
set table_name_str = concat(table_year,'',table_month_str,'',table_day_str);
--建立使用者變數作為拼接SQL的接收變數
set @create_table_sql = concat('create table test_',table_name_str,'(id varchar(36) , name varchar(10) , age int(3))');
--prepare 預編譯拼接的SQL
prepare create_table_stmt from @create_table_sql;
--執行編譯之後的SQL
execute create_table_stmt;
--刪除執行完的預編譯變數 DEALLOCATE 可以換成 drop
DEALLOCATE prepare create_table_stmt;
--將迴圈條件+1
set table_day_index = table_day_index + 1;
--結束迴圈
end while;
end //
預編譯詳解:
prepare 預編譯變數名 from 使用者變數名(拼接之後的SQL) from後面的變數不能使用區域性變數,否則報錯
execute 預編譯變數名 執行編譯後的SQL語句
DEALLOCATE prepare 預編譯變數名 刪除執行完的預編譯變數,DEALLOCATE 可以換成 drop
儲存過程與函式的區別:
1.寫法上的區別:
儲存過程的引數列表中可以有傳入引數(in)、返回引數(out)、輸入輸出引數(inout)
函式的引數列表只能有傳入引數(in),並且有return 有效返回值,比如return 0;
2.返回值上的區別:
儲存過程的返回值可以是多個值;
函式的返回值只有一個;
3.呼叫方式上的區別:
儲存過程的呼叫方式有:
1. exec 過程名;
2. execute 過程名;
3. 可以在PL/SQL直接呼叫;
函式的呼叫方式有:
----呼叫FUNCTION add_three_numbers為例
----1. 位置表示法呼叫函式
BEGIN
dbms_output.put_line(add_three_numbers(2,4,5));
END;
----2. 命名錶示法呼叫函式
BEGIN
dbms_output.put_line(add_three_numbers(b=>3, a=>4,c=>2));
END;
----3. 混合使用位置表示法和命名錶示法呼叫函式
BEGIN
dbms_output.put_line(add_three_numbers(3, b=>4,c=>2));
END;
----4. 排除表示法
BEGIN
dbms_output.put_line(add_three_numbers(12,c=>2));
END;
----5. sql呼叫表示法 --混合表示法
SELECT add_three_numbers(3, b=>4,c=>2) FROM DUAL;
一切都是最好的安排。