Creating stored procedure again in MySQL DB - mysql

I created a stored procedure, 'myProc', in a MySQL database.
Then I dropped this procedure.
I wanna create again a procedure with the same name to the before.
I create the procedure again and name it 'myProc'.
CALL myProc();
But, when I execute this procedure, it is an error like that "PROCEDURE myProc does not exit".
Also code is same to the before one.

Unable to call a stored procedure in MySQL
You've created a procedure in MySQL 5. You've granted EXECUTE privileges to your application's user account. But when your application prepares a statement to call that procedure, an exception is thrown. Perhaps it's a NullPointerException deep inside of ConnectorJ. Perhaps the exception claims that the procedure does not exist. Or perhaps you've gotten lucky enough to get the exception that leads you down the right path(Driver requires declaration of procedure to either contain a ''\nbegin'' or ''\n'' to follow argument declaration, or SELECT privilege on mysql.proc to parse column types). Here are the troubleshooting steps that I've gleaned from hours of searching the MySQL forums.
First, open two console windows. In one, log into MySQL as the application user. In the other, log in as root. In your app window, list the databases.
SHOW DATABASES;
If your application's database does not appear, then you should go to your root window and grant database privileges.
USE mydatabase;
GRANT ALL ON mydatabase TO appuser;
Now go back to the app window. List the databases again to ensure that it appears. Now that it does, go into it.
USE mydatabase;
Once you're in, try to view the procedure.
SHOW CREATE PROCEDURE myproc /G
One of three things will happen. If you get a message saying "PROCEDURE myproc does not exist" then the app user does not have privileges for it. Go back to the root window and grant them.
GRANT EXECUTE ON PROCEDURE myproc TO appuser;
The second thing that might happen is that the procedure will be found, but the body will not be listed. Instead, it will say "Create Procedure: NULL". If so, go back to the root window and take care of that.
GRANT SELECT ON mysql.proc TO appuser;
The third thing that could happen is what you want to happen; the body of the procedure will be listed. Now you should be able to call the procedure from your application.
Warnings
You may be tempted to take a couple of short-cuts to resolve problems like these. Please don't. Shortcuts may cause bigger problems down the road.
The first thing you might try is to use the root account from within your application. This is extremely dangerous. Security comes in layers. While you should use stored procedures and prepared statements to avoid SQL injection attacks, you should also apply the principle of least privilege just in case they occur anyway. Allowing your application to connect as root gives an attacker access to your most valuable resource: your data. But giving each part of the application a separate account with only the privilege that it requires quarantines the bad guy.
The second thing that you might try after hours of research is to set the "noAccessToProcedureBodies" flag in the ConnectorJ connection string. Please avoid this flag, as it circumvents the parameter type checking that the JDBC driver provides for you. This flag causes ConnectorJ to convert all of the parameters to strings, which MySQL will then convert back to the required type.
But by walking through the problem step-by-step, these short-cuts should not be necessary.
Reference
http://adventuresinsoftware.com/blog/?p=74

Related

AWS Aurora for MySql problem with a procedure that call other procedures having different number of parameters

I have a cluster (2 instances) on AWS Aurora with mysql 5.6 with a lot of stored procedures running, and never had a problem.
Yesterday I added a new stored procedures, "new_procedure_7" and successfully tested (a simple stored procedure, with no parameters, that make a select).
Then I called this procedure from inside another procedure, already existing and working, that calls a set of stored procedures (all already present and working).
This is the situation (I removed transaction and sqlexception handler):
CREATE PROCEDURE my_cumulative_procedure(
IN p_param1 VARCHAR(7),
IN p_param2 INT
)
SQL SECURITY INVOKER
BEGIN
CALL procedure_0(p_param1, p_param2);
CALL procedure_1(p_param1, p_param2);
CALL procedure_2(p_param1, p_param2);
CALL procedure_3(p_param1, p_param2);
CALL procedure_4(p_param1, p_param2);
CALL procedure_4(p_param1, p_param2);
CALL procedure_6(p_param1, p_param2);
CALL new_procedure_7();
END
The two parameters of "my_cumulative_procedure" are used for all the procedures but the last one, which has no parameters.
"my_cumulative_procedure" is used to retrievea data for an api (aws lambda).
I developed all this modification in a local vm with debian 9 and mysql 5.6, and tested the api with Serverless framework (and serverless-offline plugin). All works correctly.
Then i deployed all the modification in a dev db cluster (AWS Aurora with mysql 5.6), and here started the problems.
When I call the api, the resultset from procedure_0 to procedure_6 continue always to work correctly, but new_procedure_7 start having problem. Sometimes it is correctly executed and returns the right data, sometimes it is executed, but return an empty set (wrong), and all the other times it give a 1045 error: access denied for user 'xyz'#'%' (using password: YES).
But the user xyz have all the rights needed (in fatct with that user I can succesfully call new_procedure_7 without having errors).
So I started testing different solutions.
I changed the order, swapping procedure_6 with new_procedure_7: same results
I putted new_procedure_7 as the first procedure called (before procedure_0): all run correctly, never have an error
I keep original order (new_procedure_7 is the last called), but I've added the parameters like in the others procedures, obtaining "CALL new_procedure_7(p_param1, p_param2);": all run correctly, never have an error
I removed "CALL new_procedure_7();" and putted in its place the code of the procedure (select bla bla bla from ...): all run correctly, never have an error.
So the problem is that I have a procedure with no parameterf after a set of procedures with parameters. I have tested this in another procedures that make multiple call and I finded the same problem: here the procedure with no parameters is the first called and if I move it at the last place, the problems start.
I don't want to add unnecessary parameters to the procedure just to make it work (moreover new_procedure_7 can also be called individually), and I can't change the order of the calls inside my_cumulative_procedure, because it is already used.
I missed something? There is something to do?
Is it a problem of mysql 5.6? (but in my vm I had no problems)
Is it a problem of Aurora for mysql 5.6? (Aurora version 1.22.2)
And above all, is there a solution?

mysql Stored procedures can be seen but cannot be executed by authorised user

I have created a small DB (MariaDB, in a XAMPP environment) for my group, and we are currently using phpmyadmin to interact with the DB. I have created users and given them different permissions depending on their specific usage needs; and this works fine for tables and views. However something seems wrong with stored procedures. I need to give the user Global SELECT and EXECUTE privileges in order for them to run them. If I do it at the database level procedures can be seen but cannot be executed.
I normally create the procedures from mysql workbench, and the look like this:
CREATE DEFINER=`root`#`localhost` PROCEDURE `proc_name`()
BEGIN
...
END
And users are like:user1#% although I have also tried creating user like user1#localhost but it doesn't help.
Any idea why this is happening? Does it have to do with the DEFINER?
Many thanks in advance!

MySQL (5.7) drop stored procedures via mysql.proc

Summary: Can DELETE from mysql.proc be used safely from MySQL 5.7 onward?
In question Drop all stored procedures in MySQL or using temporary stored procedures, it was mentioned that in MySQL it is not possible to use DROP PROCEDURE inside a stored procedure (mysql error code 1357, "Can't drop or alter a %s from within another stored routine").
Empirically:
DELETE from mysql.proc WHERE db = <db-name> AND name LIKE '<procedure-prefix>%';
does seem to work fine instead.
In a comment, the question was asked (but not answered):
Is mysql.proc still a viable method of interacting with MySQL meta information in 5.7?
Even though I fully realise it is not "desirable", is it "OK" to use this in MySQL 5.7? Or, is there some vital stuff which DROP PROCEDURE does, such that I must not use this workaround?
The direct delete from the procs table does not seem to take an immediate effect in the current MySQL session.
The flush statement is used in MySQL to make the server reload stuff (changing the privileges directly via update / delete and the flush privileges is probably the best analogy). However, I could not find any versions of flush that would affect the stored procs based on the documentation. So, I do not think there is any way to make the deletion of the stored proc final in the current MySQL session.
The real danger with your direct deletion approach is that it relies on an undocumented feature of MySQL. This feature may change without any notice in a future version of MySQL, making an upgrade impossible. Also, without actually debugging MySQL itself, it is very difficult to say if your approach has any unintended side effects.
For these reasons, I would not recommend to use this approach in a production code. If it is a one-off exercise, then you may get away with it.

Does MySQL support interior mutability or sticky bit?

Say, I have a complex MySQL procedure. The procedure is basically a complex SELECT query that use data inside a table to output some records.
For convenience, the procedure need to write to a temporary table to calculate the final result.
So can I grant properly so that a user that can only read the database can call this procedure to get its output, although the procedure actually need to write to the database? Because essentially this procedure don't intend to write, it just cache some data to a specific table with a name start with underscore so it shouldn't break anything seriously, beside costing storage of disk.
A stored program or view that executes in definer security context executes with the privileges of the account named by its DEFINER attribute. These privileges may be entirely different from those of the invoking user.
https://dev.mysql.com/doc/refman/5.7/en/stored-programs-security.html
As long as the user defining the procedure has the necessary permissions and doesn't explicitly force the procedure to run in INVOKER context, the permissions of the invoking user have no impact on what the procedure can do. The permissions of the defining user apply to the procedure's actions.
The invoking user only needs to be able to run it. No special arrangements are necessary, because this is the default behavior.
The DEFINER defaults to the user creating the procedure. If that account has the SUPER privilege, they can actually declare a different definer account whose privileges will apply.
Typically, stored procedures in MySQL operate with privileges associated with the procedure's definer, not the user who invokes the procedure, who only needs execute privilege on the procedure.
A stored procedure can be configured to run in invoker context, thus executing with same privilege as the invoking user, but this is not common.
Just make sure when you define the procedure the definer has appropriate permission to do everything that needs to be done during execution.

MySQL: What effect does DEFINER have on procedures and functions?

I use SQLyog to write procedures and functions in a remote MySQL database I am developing. The database has only one username/password. It is accessed via a front end executable application that I have written in Delphi and which is used by a couple of dozen different people, all using the same username.
When I use SQLYog to write a procedure using, for example,
CREATE PROCEDURE age_frequency_count(IN bin_size INT)
The resulting procedure gets the definer put in whether I like it or not, resulting in
CREATE DEFINER=<the_user_name>#<my_IP_address> PROCEDURE age_frequency_count(IN bin_size INT)
(I think this is being done by MySQL, not by the SQLYog DBMS.)
From reading the documentation and from posts here on SO, I have a rough, but rather confused idea of how the definer is used to say what permissions are needed to execute, or maybe alter, the procedure and what the procedure is allowed to do, but I would welcome some clarification.
Question
If my IP address is in the definer, can the procedure still be executed by other people who will be logging in from a different IP address (although with the same username)?
Can someone please clarify what the definer is doing? i.e. what can a connection from my IP address do that connections from other IP addresses can't?
I use the DEFINER clause to create a stored procedure with the security privileges of a powerful user that also has UPDATE, DELETE, SELECT, and INSERT rights to a particular database table. Then, I only grant EXECUTE on that stored procedure to a minon user (some people call it a www user, versus the more powerful wwwproxy user).
In this way, the minion can only execute designated stored procedures and has no UPDATE, DELETE, SELECT, INSERT, or other rights on a database table.
I hope that helps frame the idea behind the DEFINER clause. Use it to separate power from tasks.
You are correct, by default, MySQL uses the identity of the current user as the DEFINER when creating a stored procedure. This identity could be the identity of the front-end application (so to speak), or, like I said, you can use a proxy user that has normal table privileges. Then the application user would be the minion with only one privilege on the stored procedure, EXECUTE.
In short, if the default DEFINER user does not represent what the front end application uses to login to the database, and you want it to, then you need to change the stored procedure with ALTER, if possible.
On the other hand, the better idea would be to use the minon/proxy scenario. Application users on the Internet have no bearing on the IP that ends up in the stored procedures DEFINER clause. All that matters is the IP of where your app is logging in from to MySQL. Your app is talking to the database, not user agents on peoples' computers. However, that notion is, generally, a point of initial confusion. You are fine!
Hope that helps.