mysql存儲過程及函數

注意:mysql中的用戶變量的生命週期是會話級的,不是語句級的!

存儲過程--------------------------------------------------
drop procedure if exists usp_simple;

delimiter //

create procedure usp_simple(in ip int, out op int, inout iop int)
begin
 select count(*) into op from t1;
 set op = op + ip;
 set iop = iop * 2;
end;
//

delimiter;

執行:
set @iop = 3;
call usp_simple(6,@op,@iop);
select @op,@iop

------------------------------
drop procedure if exists usp_simple2;
delimiter //
create procedure usp_simple2()
begin
 select * from t1;
end;
//

delimiter;

執行:
call usp_simple2();

函數------------------------------------------------------
delimiter //
CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hello, ',s,'!');
//
delimiter ;
 
SELECT hello('world');


-------------------------------------------------------------
注意在複製系統裏,存儲過程和函數的確定性,這一點非常重要!!!!

在主服務器上,除非子程序被聲明爲確定性的或者不更改數據,否則創建或者替換子程序將被拒絕。默認情況下創建SP或者FN肯定會遇到1418的錯誤號。

解決辦法:
在選項文件裏,配置log_bin_trust_routine_creators=1。Mysql會認爲所有創建子程序的創建者都是可以信任的,創建的子程序都是確定的。

不確定性子程序舉例:
1. ------------------------------------
CREATE FUNCTION myfunc () RETURNS INT
·                BEGIN
·                  INSERT INTO t (i) VALUES(1);
·                  RETURN 0;
·                END;
按照上面定義,下面的語句修改表t,因爲myfunc()修改表t, 但是語句不被寫進二進制日誌,因爲它是一個SELECT語句:
SELECT myfunc();
2.--------------------------------------
delimiter //
CREATE PROCEDURE mysp ()
BEGIN
  IF @@server_id=2 THEN DROP DATABASE accounting; END IF;
END;
//
delimiter ;

CALL mysp();
CREATE PROCEDURE和CALL語句將被寫進二進制日誌,所以從服務器將執行它們。因爲從SQL線程有完全權限,它將移除accounting數據庫。

發佈了25 篇原創文章 · 獲贊 6 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章