今天将一份服务器上的sql脚本导入到本地做测试,一切配置完毕后发现程序跑不起来,经过调试后发现问题所在:数据库中所有的存储过程的definerdev@%,所有视图都因为definer错误打不开。

很明显错误原因是本地数据库没有dev这个用户,而存储过程是需要用dev用户的权限来调用的,于是我创建一个相同名称的用户,授权对该数据库的所有操作权限,问题就解决了。

那么,这里的definer是什么意思,与另一种定义方式invoker又有什么区别?

DEFINER与INVOKER的区别

我们在创建存储过程的时候,需要定义存储过程的安全验证方式SQL SECURITY,可以设置为DEFINERINVOKER,表示这个存储过程执行的时候,是使用谁的权限来执行的。DEFINER表示由DEFINER属性所指定的用户的权限来执行,INVOKER表示以调用这个存储过程的用户的权限来执行。

DEFINER

当定义为DEFINER时,必须数据库中存在DEFINER指定的用户,并且该用户拥有对应的操作权限,才能成功执行。与当前用户是否有权限无关。

定义为DEFINER的存储过程:

CREATE DEFINER=`dev`@`%` PROCEDURE `p_user_login`(IN u_name VARCHAR(25), IN u_password VARCHAR(100))
BEGIN

  SELECT u.id, u.name, u.tid, u.status, u.is_report FROM v_user u WHERE u.name=u_name AND u.password=u_password AND u.status=1;

END;

INVOKER

当定义为INVOKER时,只要执行者有执行权限,就可以成功执行。

定义为INVOKER的存储过程:

CREATE DEFINER=`dev`@`%` PROCEDURE `p_user_login`(IN u_name VARCHAR(25), IN u_password VARCHAR(100))
    SQL SECURITY INVOKER
BEGIN

  SELECT u.id, u.name, u.tid, u.status, u.is_report FROM v_user u WHERE u.name=u_name AND u.password=u_password AND u.status=1;

END;