注意: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数据库。