Problems calling MySQL stored procedures from C API - mysql

I have a problem calling a stored procedure on my MySQL server using the C API.
I use mysql_query(&handle,"CALL myprocedure") but the function fails (returns 1) and error lookup gives
the following message "Procedure myprocedure can't return a result set in the given context."
I even tried to use mysql_real_query insted, but no better.
I've seen a few topics about this bug, but only PHP related. So there seems to be the same problem for C programs too.
The weird thing is that my stored procedure is not even supposed to return any result set. It just works with data in tables, doesn't really return anything.
Thanks for any advices.

Refer to functions:
mysql_set_server_option() &
mysql_real_connect()
here.
Multiple statements are only enabled(temporarily) using the MYSQL_OPTION_MULTI_STATEMENTS_ON and _OFF arguments
to mysql_set_server_option().
The problem here is that CLIENT_MULTI_STATEMENTS in
mysql_real_connects()
implicitly enables CLIENT_MULTI_RESULTS, too, but
MYSQL_OPTION_MULTI_STATEMENTS_ON only enables multiple statements,
not multiple results.
So add CLIENT_MULTI_STATEMENTS on connect and try again.

Did you try to call this procedure from 'mysql' command line client?
Are you able to call (another) empty procedure to test if problem is related to the procedure?

Related

MySQL Stored Procedure Read Replica Issue - Strange Stored Procedure/Function Behavior

UPDATE 11.15.2022
I have conducted extensive testing and found the pattern of problem here. Once again, what's strange is this ONLY happens if you pass a function as a parameter to the originating Stored Procedure; passing a hardcoded value or variable works just fine.
The issue is when the Stored Procedure calls another Stored Procedure that checks ##read_only to see if it can WRITE to the database. I confirmed removing any code that writes data fixes the issue -- so ultimately it appears passing a STATIC value to the SP causes the procedure execution to bypass any writing (as expected) because of the IF ##read_only = FALSE THEN ...write...
It seems passing a function somehow causes MySQL to compile a "tree" of calls and subcalls to see if they CAN write rather than if they DO write.
It appears the only way to work around this is to pass the parameters as variables rather than function calls. We can do this, but it will require substantial refactoring.
I just wonder why MySQL is doing this - why passing a function is causing the system to look ahead and see IF it COULD write rather than if it does.
We have a Read Replica that's up and running just fine. We can execute reads against it without a problem.
We can do this:
CALL get_table_data(1, 1, "SELECT * from PERSON where ID=1;", #out_result, #out_result_value);
And it executes fine. Note it's READS SQL DATA tagged. It does not write anything out.
We can also do this:
SELECT get_value("OBJECT_BASE", "NAME");
Which is SELECT function that is READ ONLY.
However, if we try to execute this:
CALL get_table_data(1, get_value("OBJECT_BASE", "NAME"), "SELECT * from PERSON where ID=1;", #out_result, #out_result_value);
We get the error:
Error: ER_OPTION_PREVENTS_STATEMENT: The MySQL server is running with the --read-only option so it cannot execute this statement
We're baffled at what could cause this. Both the SP and function are read-only and execute individually just fine, but the second we embed the function result in the call of the SP, the system chokes.
Any ideas?
So AWS cannot figure this out. The issue only happens when a function is passed as a parameter to a stored procedure that calls another stored procedure (not even passing the value of the function) that has a ##read_only check before doing an INSERT or UPDATE. So for some reason, the system is doing a pre-scan check when a function is passed vs. a variable or hardcoded value.
The workaround is to pass the function value as a variable.
I'm going to report this issue to Oracle as it might be some sort of bug, especially given the function is DETERMINISTIC.

How to execute a MySQL stored procedure or function in Flask-SQLAlchemy

I made a Stored Procedure with MySQLWorkbench and tested it on that platform. The Stored Procedure runs fine on MySQLWorkbench but if I run the Stored Procedure with Flask-SQLAlchemy, I don't get any error but I don't see the results in the table.
I have tried the following ways of executing a stored procedure:
db.engine.execute("CALL stored_procedure_name(%s, %s)", (parm_1, parm_2))
This results in no error, but the function doesn't give the same results (in the database) as if i run the same function (with the same parameters) as in MySQLWorkbench.
I also tried:
db.engine.execute(func.stored_procedure_name(parm_1, parm_2))
It returned that stored_procedure_name was not a function, so I also created a function that was (almost) identical to the stored procedure, and run it using the same code, but it still doesn't run the function properly and does not return an error.
So after some reading of the documentation I found the answer. I still want to keep the question, because I think it is useful for some people.
You can run a function (so not a stored procedure) with the following code
db.engine.execute(text("SELECT function_name(:parm_1, :parm_2)").execution_options(autocommit=True), :parm_1 = :parm_1, :parm_2 = :parm_2)

Are QSql::Out and QSql::InOut used outside of calling a store procedure?

I am using Qt5 to access a MySQL database. It is easy to execute INSERT queries using QSqlQuery + prepare() + bindValue().
Now I noticed that bindValue() has an optional paramType parameter that can be set to QSql::Out and QSql::InOut.
Is it correct that the QSql::Out and QSql::InOut arguments are useful when CALLing procedures and that they have no use for lets say a SELECT statement? Are there other use cases than CALL?
It turned out that QSql::Out and QSql::InOut are actually intended for use with procedure calls only.
However it also turned out that Qt/MySQL parameter binding does not support the mentioned OUT and INOUT parameters types (see here).

Running Stored Procedure from Matlab Only Returns 1 row

I am retrieving data from a mysql database in matlab.
conn=database('my_database','','');
sql = 'call latest_hl_tradables()';
curs = exec(conn,sql);
curs = fetch(curs);
Yesterday, the code returned 600 rows. This morning, it returns 1 row. If I run the stored procedure (latest_hl_tradables) in MySQL Workbench, it still returns 600 rows.
Strangely, it the code started working again.
All I did was write some diagnostic code to count the number of records in the tables that latest_hl_tradables() queries. Initially those only returned 1 row. Then when they started returning all the rows. I don't know what changed.
(My configuration is R2014b / SQL Server 2014 / MS JDBC 4.0. I believe the OP describes a generic issue, not database-vendor-specific)
I have also experienced unreliable results within MATLAB from stored procedures which return result sets. I submitted a service request to Mathworks. The short answer is that in this use case, neither of the Matlab Database Toolbox functions exec or runstoredprocedure are appropriate. Rather, stored procedures should be called from MATLAB via runsqlscript. Here's the tech's response:
Unfortunately there is no way to get output of the query using the
cursor object. The only way to get the output on DML is by running
them as a script. The syntax is:
>>results = runsqlscript(connObject,'ScriptName.sql')
where the SQL queries are placed in the file "ScriptName.sql".
This will return cell array of results as the output
Note that this solution makes life complicated when your stored procedure requires input parameters. In typical cases when sp parameters aren't known a priori, this means you have to generate a custom SQL script on-the-fly & write it out to disk.

How do i output an SQL Error in MySQL

I've declared an handler which will handle SQLEXCEPTION, in the clean up code i had it do SELECT 'My Handle';, i ran a script that fails because of a primary key violation and it worked cause i got my output.
the problem with DECLARE ... HANDLE FOR SQLEXCEPTION is that when there is an error it will run though it's doesn't say what error triggered it, so i want to output the error
How do i output the SQL Error using a MySQL Query, i don't care if i can only output the error code/id i just need something to output giving me an indication on what the error is so i can fix the problem
EDIT: in case if it's not obvious, this code is in an SQL Procedure
There is nothing in the DECLARE HANDLER documentation on this functionality. You could handle the errors MySQL returns to your application and print or log them that way.
I actually haven't used any handles, but i think you can make your code into a stored procedure and then run the stored procedure!! You might find MySQL accepts what you are trying to do then.