I have searched through the internet, and understand that the only way to change the body of a store procedure is by dropping and creating it again. There seems nothing wrong with the mechanism but if I have a client application (or thousands of distributed clients) that keeps invoking the store procedure to update some data on the server database, dropping the procedure would result in data lost and/or corruption.
I'm thinking if there is a syntax like "CREATE PROCEDURE IF EXIST..." or something functions similarly so the update operation would be carried out smoothly. Yet I didn't find such thing being available in MySQL.
So how do you guys think this issue can be addressed? Awesome thoughts?
You cannot modify a stored procedure (though you can change its characteristics) in MySQL. From the ALTER PROCEDURE page.
This statement can be used to change the characteristics of a stored
procedure. More than one change may be specified in an ALTER PROCEDURE
statement. However, you cannot change the parameters or body of a
stored procedure using this statement; to make such changes, you must
drop and re-create the procedure using DROP PROCEDURE and CREATE
PROCEDURE.
While it is possible to lose data while performing this update (though it should be a relatively small window), it's unlikely that your data will be corrupted. I'd take a look at message queuing technologies if your system needs to be guarded against data loss from database downtime.
Related
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.
I am getting the following message while creating a stored procedure in MySQL Workbench:
"Review the SQL script to be applied on the database"
I have several tables inside the database but the stored procedure I am writing will be
used only for one table. Since, the SQL script of stored procedure is gonna apply on the whole database, I am wondering if it's gonna affect other tables as well? I don't want other tables to get disturbed because of this script.
Please provide your inputs as I am doing this for the first time.
Question #2:
Why do I see "DELIMITER $$" as the first statement while creating a routine before the following statement?
CREATE PROCEDURE `mydatabase`.`myfirstroutine` ()
BEGIN
Thanks
1) MySQL Workbench offers the option to review the generated SQL script before it is sent to the server. This way you can check it for possible problems.
2) The DELIMITER command is usually necessary to switch the current delimiter that ends a single statement (which is by default a semicolon) to something else because the stored procedure code itself needs the semicolon to separate individual commands. However the sp code must be sent as a whole to the server.
A few more details: the DELIMITER keywword is a client keyword only, that means the server doesn't know it and doesn't need it. It's an invention for clients to properly separate sql commands before sending them to the server (you cannot send a list of commands to a server, only individual statements).
In MySQL Workbench however, especially in the object editors where you edit e.g. the sp text, adding the DELIMITER command is essentially nonsense, because there's only this sp code, hence nothing to separate. This might disappear in future version but for now just ignore it.
I have a .dbml with one table and that table have associated behavior for update/delete/insert which are stored procedures.
If I query a row and I'm not modifying it or I set the same value that was there and I call datacontext.save(), it won't execute the stored procedure.
Is there a way to know that it won't be executed or force it?
You can force the stored procedure to execute by tricking linq2sql to think that a column is always 'dirty'. The answer to this question may help:
Can you convince a DataContext to treat a column as always dirty?
I created a stored procedure which ran successfully but I can't seem to find the procedure in the usual place within the database and I can't execute the procedure in Excel but I can drop the procedure.
I am confused.
I have written many stored procedures and never had this problem. Thanks in advance.
Sounds like something I've done before: inadvertently added the stored proc to the master database rather than the database I thought I was working in.
Check the master database under System Databases.
To prevent this in the future, you may want to consider adding a use dbname statement in the script.
Sometimes an application requires quite a few SQL queries before it can do anything useful. I was wondering if there is a way to send those as a batch to the database, to avoid the overhead of going back and forth between the client and the server?
If there is no standard way to do it, I'm using the python bindings of MySQL.
PS: I know MySQL has an executemany() function, but that's only for the same query executed many times with different parameters, right?
This process works best on inserts
Make all you SQL queries into Stored Procedures. These eventually will become child stored procedures
Create Master Store procedure to run all other Stored Procedures.
Modify master Stored procedure to accept values required by child Stored Procedures
Modify master Stored procedure to accept commands using "if" statements to know which
child stored procedures to run
If you need return data from Database use 1 stored procedure at the time.