1. 程式人生 > 其它 >MySQL儲存過程入門基礎

MySQL儲存過程入門基礎

建立儲存過程無參語法:

	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;
一切都是最好的安排。