Bulk Insert statements MYSQL Stored Procedure - mysql

I have a stored procedure where I need, amongst other things, to be able to do multiple inserts to a particular table.
The number of inserts to this table can vary.
The stored procedure is being called via JDBC.
Passing parameters for a single insert statement to a stored procedure is easy. Is there a way I can pass an array of values to the stored procedure, and then loop through the array to perform the insert statements?
I'm pretty new to stored procedures, so thanks in advance for all your help....

This was achieved by including everything in a transaction and it will automatically rollback if anything goes haywire. THis is done in JDBC by setting the connection autocommit to be false, and then autocommiting
conn.setAutoCommit(false);
conn.commit();

Related

How to update a table from a trigger, when column name is dynamic?

Schema and data for test database - https://gist.github.com/koceg/435c0d2b1246a69d048f
My goal is to update boards table, when somebody inserts a new row in the objects_properties table. The name of the column to update is dynamic - it depends on a property_id from objects_properties.
So far I've created a trigger and a stored procedure, but I'm getting this error:
Dynamic sql is not allowed in stored function or trigger.
Am I doing something wrong or is mysql not allowing to call a stored procedure with a prepared statement inside a trigger? If so, how can I do what I want?
I have an idea, but it's ugly even in a pseudocode. Real SQL will be even worse, because there will be a few dozens codes:
SWITCH (property_code)
CASE 'name'
INSERT INTO boards (id, name) VALUES (#object_id, #value) ON DUPLICATE KEY UPDATE name = #value;
CASE 'address'
INSERT INTO boards (id, address) VALUES (#object_id, #value) ON DUPLICATE KEY UPDATE address = #value;
CASE 'district'
INSERT INTO boards (id, district) VALUES (#object_id, #value) ON DUPLICATE KEY UPDATE district = #value;
P.S. I can't move this logic to my application, because this database is used by several applications.
The Current MySQL (5.7) Manual section D.1 Restrictions on Stored Programs states that
SQL prepared statements (PREPARE, EXECUTE, DEALLOCATE PREPARE) can be used in stored procedures, but not stored functions or triggers. Thus, stored functions and triggers cannot use dynamic SQL (where you construct statements as strings and then execute them).
Generally, statements not permitted in SQL prepared statements are also not permitted in stored programs. For a list of statements supported as prepared statements .
Because local variables are in scope only during stored program execution, references to them are not permitted in prepared statements created within a stored program. Prepared statement scope is the current session, not the stored program, so the statement could be executed after the program ends, at which point the variables would no longer be in scope.
So you can see that it's not permitted.
Regards.

Calling stored procedure after user inserts data to a table

I need help with calling a stored procedure. Let me explain briefly what the problem is.
I have a "booking" table and whenever new booking is made and new data is inserted into the booking table, I need to call a stored procedure which aims to update field in another table. I have problem with calling the stored procedure after user inserts data into "booking". I don't want to use trigger it needs to be SP. Do you guys think I can use something like AFTER INSERT table_name CALL stored_procedure(). etc
Any help is welcome.
Thanks a lot.
What you are describing is an AFTER INSERT TRIGGER. You can put your store procedure within the trigger although is not recommendable.
Options you have:
Call a trigger made by sql code (no store procedures)
Wrap the INSERT and the CALL to your SP inside a TRANSACTION

save stored procedure output into a table

I have execute only access to a stored procedure.
This SP seems to select some data from multiple tables, and returns one row. I need to store two columns of the output of this SP into a table.
Is there any way to do this within MySQL?
If it returns a row, this is a stored function and not a stored procedure. You can use something like the following to insert into your table:
INSERT INTO tablename SELECT (SELECT col1, col2 FROM (SELECT somefunction()))
Otherwise, it will be a stored procedure and you should do something like this, assuming that #var1 and #var2 are output parameters:
CALL someprocedure(#var1, #var2, #var3)
INSERT INTO tablename SELECT(#var1, #var2)
See the documentation about Create Procedure and Create Function for more information about functions versus procedures.
MySQL has an extension to stored procedures that allows the procedure to return one or more result sets to the client, as if the client had issued a SELECT query... but those results are ephemeral. They don't persist and they can't be stored in variables or otherwise accessed after the procedure finishes -- they can only be "fetched" the one time.
There is a way to make them accessible without breaking the way the procedure already works, as I discussed here, but you can't do it without a change to the procedure:
How to use Table output from stored MYSQL Procedure
The idea is for the procedure to write its output in a temporary table, and then return it to the caller by calling SELECT against the temporary table -- but to leave the temporary table behind so that the caller can access it directly if desired.
That's not exactly the same as what you're asking though, which is why I didn't mark this question as a duplicate, since you, unlike the other poster, do not appear to have administrative control of the procedure... but unless you can make the case for a change like this, there's not another way within MySQL to access those returned values, since they only exist in the result-set that's returned.
Of course, procedures do have optional OUT parameters, where you can hand variables to the procedure as part of arguments you use to call it, and it can set those variables, so that they'll have the values you need when the procedure is done, but that only works when the return values are scalars and would require a change to the procedure's interface, since procs in MySQL do not have "optional" arguments... if the procedure were changed to permit this, it would require an increased number of arguments to be provided every time it was called, and if other components are calling it, that could easily break other things.

MYSQL 5.5 Nested Stored Procedure Error Handling

I'm using MYSQL 5.5, How to do Error Handling with Nested Stored Procedure. Pretty much most of the stored procedure, does truncate table, insert into select * from and insert into on duplicate key update.
If there is any issue with any of the nested stored procedure, I would like to catch that error or tell me that error happened in that particular stored procedure.
Right now, due to the nested stored procedure, there is no way for me to know,
in which stored procedure, the exception happended.
Within each stored procedure, you can DECLARE ... HANDLER for the errors in which you're interested and have them write state information to a temporary table; that table can subsequently be read by other (outer) stored procedures to determine what error(s), if any, were raised.

MYSQL Trigger recursion avoidance

I have a general AFTER UPDATE trigger for my users table to check if a column has changed, and if so, call a stored procedure.
The problem is the stored procedure does some calculations and itself updates a field in users.
How do I avoid the recursion if my stored procedure updates the users table, which invokes the trigger, which again invokes the stored procedure?
Thanks!
MySQL doesn't let you disable triggers (without dropping and recreating them), but you have a couple of options:
Don't update the users table from within the procedure.
Add a field to the users that the procedure would set to a specific value on update. When the trigger sees that value for that field, don't call the procedure.
Use a global variable to accomplish the above (NOT connection safe - will disable triggers for all connections).