通过jdbc执行的存储过程

发布于 2024-12-11 17:56:38 字数 2652 浏览 0 评论 0原文

我在 mysql 数据库上创建了一些存储过程,但是当我尝试执行它们时,我得到:

User does not have access to metadata required to determine stored procedure parameter types. If rights can not be granted, configure connection with "noAccessToProcedureBodies=true" to have driver generate parameters that represent INOUT strings irregardless of actual parameter types.

我在连接字符串中添加了 noAccessToProcedureBodies=true,但我仍然收到此消息。我使用 DriverManager.getConnection(url, user, password) 方法,我使用的 url 是

jdbc:mysql://[server-url]/[database-name]?noAccessToProcedureBodies=true 

编辑:我的意思是我有一个名为 creautenti 的用户,我在此方法中使用它来创建新用户:(

public static boolean creazioneUtente(String user, String password) throws EccezioneDaMostrare{
    if(apriConnessione(CREA_UTENTI_USER, CREA_UTENTI_PW, false)){
        try{
            conn.setAutoCommit(false);
            String sqlCommand="CREATE USER ? @'%' IDENTIFIED BY PASSWORD ?";
            String sqlCommandGrant="GRANT EXECUTE ON salvataggi.* TO ? REQUIRE SSL;";
            String sqlCommandGrantEx="GRANT SELECT ON `mysql`.`proc` TO ? @'%';";
            PreparedStatement s=conn.prepareStatement(sqlCommand);
            PreparedStatement sGrant=conn.prepareStatement(sqlCommandGrant);
            PreparedStatement sGrantEx=conn.prepareStatement(sqlCommandGrantEx);
            s.setString(1, user);
            sGrant.setString(1, user);
            sGrantEx.setString(1, user);
            s.setString(2, mySQLPASSWORD(password));
            s.execute();
            sGrant.executeUpdate();
            sGrantEx.executeUpdate();
            conn.commit();
            conn.setAutoCommit(true);
            chiudiConnessione();
            return true;
        }
        catch(SQLException e){
            try {
                conn.rollback();
            } catch (SQLException e1) {
                String msg=String.format("Errore durante la connessione al server MySQL:\n Messaggio:%s \n Stato SQL:%s \n Codice errore:%s", e.getMessage(), e.getSQLState(), e.getErrorCode());
                throw new EccezioneDaMostrare(msg);
            }
            chiudiConnessione();
            return false;
        }
    }
    else
        return false;
}

第一个line 只是以 creautenti 的形式打开与服务器的连接,而 conn 是 Connection 对象)。因此,我以 root 身份登录服务器,并

GRANT SELECT ON `mysql`.`proc` TO 'creautenti'@'%' WITH GRANT OPTION;

相应地调用了 which 更新了 creautenti 的权限,但是当我

GRANT SELECT ON `mysql`.`proc` TO '<username>'@'%';

在任何其他用户上以 creautenti 身份登录时,权限不会被修改。所有例程都在 salvataggi 中,我向每个用户授予 EXECUTE 权限,所以我认为这也不是问题。

I've created some stored procedures on a mysql database, but when I try to execute them I get:

User does not have access to metadata required to determine stored procedure parameter types. If rights can not be granted, configure connection with "noAccessToProcedureBodies=true" to have driver generate parameters that represent INOUT strings irregardless of actual parameter types.

I added to my connection string noAccessToProcedureBodies=true, but I still get this message. I use the DriverManager.getConnection(url, user, password) method, and the url I use is

jdbc:mysql://[server-url]/[database-name]?noAccessToProcedureBodies=true 

EDIT: what I meant was that I have a user, called creautenti, that I use in this method to create new users:

public static boolean creazioneUtente(String user, String password) throws EccezioneDaMostrare{
    if(apriConnessione(CREA_UTENTI_USER, CREA_UTENTI_PW, false)){
        try{
            conn.setAutoCommit(false);
            String sqlCommand="CREATE USER ? @'%' IDENTIFIED BY PASSWORD ?";
            String sqlCommandGrant="GRANT EXECUTE ON salvataggi.* TO ? REQUIRE SSL;";
            String sqlCommandGrantEx="GRANT SELECT ON `mysql`.`proc` TO ? @'%';";
            PreparedStatement s=conn.prepareStatement(sqlCommand);
            PreparedStatement sGrant=conn.prepareStatement(sqlCommandGrant);
            PreparedStatement sGrantEx=conn.prepareStatement(sqlCommandGrantEx);
            s.setString(1, user);
            sGrant.setString(1, user);
            sGrantEx.setString(1, user);
            s.setString(2, mySQLPASSWORD(password));
            s.execute();
            sGrant.executeUpdate();
            sGrantEx.executeUpdate();
            conn.commit();
            conn.setAutoCommit(true);
            chiudiConnessione();
            return true;
        }
        catch(SQLException e){
            try {
                conn.rollback();
            } catch (SQLException e1) {
                String msg=String.format("Errore durante la connessione al server MySQL:\n Messaggio:%s \n Stato SQL:%s \n Codice errore:%s", e.getMessage(), e.getSQLState(), e.getErrorCode());
                throw new EccezioneDaMostrare(msg);
            }
            chiudiConnessione();
            return false;
        }
    }
    else
        return false;
}

(the first line just opens a connection with the server as creautenti, and conn is the Connection object). So I logged in as root on the server, and called

GRANT SELECT ON `mysql`.`proc` TO 'creautenti'@'%' WITH GRANT OPTION;

which updated creautenti's privileges accordingly, but when I call

GRANT SELECT ON `mysql`.`proc` TO '<username>'@'%';

logged in as creautenti on any other user, the privileges aren't modified. All the routines are in salvataggi, on which I give EXECUTE privileges to every user, so I don't think that's the problem either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吐个泡泡 2024-12-18 17:56:38

您最好将 mysql.proc 表的访问权限实际授予您的应用程序用户。因此,以 root 身份连接到 MySQL 数据库并运行以下命令:

GRANT SELECT ON `mysql`.`proc` TO '<username>'@'%';

然后,您的 Java 应用程序应该能够看到正确的元数据,而无需指定 noAccessToProcedureBodies=true

还要确保您连接到的用户数据库对相关过程具有执行权限。再次强调,作为 root 用户或具有授予权限的用户:

GRANT EXECUTE ON PROCEDURE db.storedproc TO '<username>'@'%';

祝你好运!

You might be better off actually granting access on the mysql.proc table to your application user. So connect to your MySQL database as root and run the following:

GRANT SELECT ON `mysql`.`proc` TO '<username>'@'%';

Your Java app should then be able to see the correct metadata without having to specify noAccessToProcedureBodies=true

Also ensure that the user under which you are connecting to the database has execute privileges on the procedure in question. Again, as root user or a user with grant privileges:

GRANT EXECUTE ON PROCEDURE db.storedproc TO '<username>'@'%';

Good luck!

铁憨憨 2024-12-18 17:56:38

太长了;将 Callable 语句更改为按索引而不是名称引用参数。

遇到类似问题后,我更新了 JDBC 驱动程序 mysql-connector-java-5.1.26-bin.jar。
然后错误从

用户无权访问确定存储的元数据
过程参数类型。如果无法授予权限,请配置
与“noAccessToProcedureBodies=true”连接以获得驱动程序
生成表示 INOUT 字符串的参数,无论
实际参数类型。

当连接配置为不访问过程体时,无法按名称访问参数

我将可调用语句更改为按索引而不是名称引用参数,嘿,它就可以工作了。

更新驱动程序可能没有必要,只需知道当您没有元数据访问或例程主体访问权限时使用索引而不是名称即可。

祝你好运

TLDR; Change your Callable Statement to reference parameters by index instead of name.

After having a similar problem I updated my JDBC driver mysql-connector-java-5.1.26-bin.jar.
The error then changed from

User does not have access to metadata required to determine stored
procedure parameter types. If rights can not be granted, configure
connection with "noAccessToProcedureBodies=true" to have driver
generate parameters that represent INOUT strings irregardless of
actual parameter types.

to

No access to parameters by name when connection has been configured not to access procedure bodies

I changed my Callable Statement to reference parameters by index instead of name, and hey presto it works.

Updating the driver may not be necessary, just knowing to use indexes instead of names when you don't have metadata access or routine body access.

Good Luck

以酷 2024-12-18 17:56:38

以下步骤在 mysql 步骤 1 中对我有用

:添加/编辑以下

Connection con = DriverManager.getConnection("jdbc:mysql://ipaddress:3306/logparser?noAccessToProcedureBodies = true ", "root", "");

第 2 步:执行以下查询
将 logparser.proc 上的所有内容授予 root@'%';

其中 logparser 是数据库名称,proc 是过程名称。

Following steps worked for me in mysql

Step 1 : add/edit following

Connection con = DriverManager.getConnection("jdbc:mysql://ipaddress:3306/logparser?noAccessToProcedureBodies = true ", "root", "");

Step 2 : Execute following query
GRANT ALL ON logparser.proc TO root@'%';

where logparser is DB name and proc is procedure name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文