mysql存储过程及函数

来源:互联网 发布:我的知乎首页没有提问 编辑:程序博客网 时间:2024/05/17 19:21

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