注意: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數據庫。