存储过程不能调用的解决方案:
出错的提示:
error:"Userdoes not have access to metadata required to determine stored procedureparameter types. If rights can not be granted, configure connection with"noAccessToProcedureBodie
引用:
最近使用root用户编写了几个存储过程,但是使用普通用户通过JDBC连接执行却报错:
java.lang.NullPointerException......
或
java.sql.SQLException: Userdoes not have access to metadata required to determine stored procedureparameter types. If rights can not be granted, configure connection with"noAccessToProcedureBodies=true" to have driver generate parametersthat represent INOUT strings irregardless of actual parameter types.
报哪个错要看你使用的Connector/J版本了。
这是因为JDBC调用存储过程时需要有showcreate procudure 权限或是有表mysql.proc的select权限。通过在JDBC连接属性中设置noAccessToProcedureBodies=true(默认false)解决或是授予普通用户相应的权限或者是按http://lists.mysql.com/commits/17817中的patch修改。
该noAccessToProcedureBodies=true的影响:
1. 调用存储过程时,将没有类型检查,设为字符串类型,并且所有的参数设为in类型,但是在调用registerOutParameter时,不抛出异常。
2. 存储过程的查询结果无法使用getXXX(StringparameterName)的形式获取,只能通过getXXX(intparameterIndex)的方式获取。
使用在URL中添加noAccessToProcedureBodies=true的影响是正式的,就是因为我添加了这个句话,导致我数据库的访问出现了问题。。。而且我使用的getXXX(String parameterName)的方式。。。
最后的解决方案:
1.以后建议大家不要使用mysql数据库的root用户来创建数据库表、存储过程等等。。。因为这样的话,你创建的存储过程就会有很多的权限,而在虚拟空间上面,只会分配给我们一些普通用户的权限,而不会有高级用户的权限。。。
来看原理吧:
查看本地mysql数据库的的Mysql数据库。。。
我们可以看到user表。。。其中user表是用户的基本表,上面有用户的密码和权限的信息:
所以你可以改变本地的权限或者联系虚拟空间的管理帮你修改权限(一般这个比较麻烦的)。。
解决办法:
1,INSERT INTO user
2,grant
第二种方式:
查看你到到处的mysql的sql文件的话,在存储过程上面。里面有root@localhost等等的权限。。。
查看存储过程:
方法一:
方法二:
1.修改mysql 存储过程的definer
修改mysql.proc表的definer字段
Sql代码
update mysql.proc set definer='author@%'
update mysql.proc set security_type='INVOKER' where db='MC';
UPDATE `mysql`.`proc` SET `definer`='author%' WHERE `db`='test' AND`name`='proc_name' AND `type`='PROCEDURE';
UPDATE `mysql`.`proc` SET `definer`='xuzhijing@%' WHERE `db`='myDB'
AND `type`='PROCEDURE';
update mysql.proc set definer='root@%' wheredb='myDb';
UPDATE `mysql`.`proc` SET `definer`='root00@%' WHERE `db`='test'AND `name`='jjjj' AND `type`='PROCEDURE';
UPDATE `mysql`.`proc` SET `definer`='wtc_678869@%' WHERE`db`='myDB' AND `type`='PROCEDURE';
2.修改security_type
Sql代码
update mysql.proc set security_type='INVOKER' where db='myDB';
(1)MySQL存储过程是通过指定SQL SECURITY子句指定执行存储过程的实际用户;
(2)如果SQL SECURITY子句指定为DEFINER,存储过程将使用存储过程的DEFINER执行存储过程,验证调用存储过程的用户是否具有存储过程的execute权限和DEFINER用户是否具有存储过程引用的相关对象的权限;
(3)如果SQL SECURITY子句指定为INVOKER,那么MySQL将使用当前调用存储过程的用户执行此过程,并验证用户是否具有存储过程的execute权限和存储过程引用的相关对象的权限;
(4)如果不显示的指定SQL SECURITY子句,MySQL默认将以DEFINER执行存储过程。
3.执行存储过程授权
Sql代码
GRANT EXECUTE ON test.* TO 'xuzhijing'@'%';
GRANT CREATE ROUTINE,ALTERROUTINE, SELECT,CREATE, INSERT, UPDATE, DELETE, EXECUTE ON test.* TO'xuzhijing'@'%' IDENTIFIEDBY '111111'
GRANT EXECUTE ON test.* TO 'xuzhijing'@'%';
GRANT CREATE ROUTINE,ALTERROUTINE, SELECT,CREATE, INSERT, UPDATE, DELETE, EXECUTE ON test.* TO'xuzhijing'@'%' IDENTIFIEDBY '111111'
CREATE ROUTINE :创建存储过程的权限
ALTER ROUTINE :修改存储过程的权限
4.删除用户
REVOKE all ON test.* FROM xuzhijing@'%'
DELETE FROM user WHERE User='user_name' and Host='host_name';
FLUSH PRIVILEGES;
在远处数据库上面使用建立存储过程,只要不要有红色的就可以了。。。。
Create Procedure |
CREATE DEFINER=`ourwishing1`@`localhost` PROCEDURE `proc_judge_mywish`(in name varchar(20)) |