ADO.NET is being used to access a MySQL database in my application. Some stored procedures were developed out of house. I applied them to the database. When trying to access a stored procedure in the database, the following exception occurs:
FUNCTION your_db.log_insertLogMessage does not exist
When calling this code:
MySqlCommand cmd = CreateCommand(procName, prams);
return cmd.ExecuteNonQuery();
The procName is string which is set correctly. Prams is MySqlParameter array. In the debugger, "?" appears for the array values, when expanding in Visual Studio.
The database seems to be accessed with no issue. I changed the database name to a dummy name and got a different error regarding the database not existing.
I removed all the stored procedures and received a new error saying a function or stored procedure with the given name did not exist.
I then reapplied the stored procedures, and I am now back to original error. The code for the stored procedure is:
CREATE DEFINER=`root`#`localhost` PROCEDURE `log_insertLogMessage`<br>
(IN `Name` varchar(100), IN `Description` varchar(5000), IN `Message` varchar(5000)
)
begin
INSERT INTO DBlog(UserName, Descr, LogMessage, WhenOccurred) values(Name, Description, Message, CURDATE());
end
I am able to call the stored procedure without issue in MySQL itself.
What am I missing?
I figured out the problem. I had to switch to an older verson mySql.data.dll. The database was set up correctly, and the code was fine. It was just a connector issue.
Related
I have a Stored Procedure wrote in SQL Server that I need to convert to MySQL, which has this code inside.
SQL server code
declare #resultatSP table (...);
...
insert into #resultatSP execute other_procedure(...);
...
My problem is that in SQL Server, the "result" of the last select done in the SP other_procedure is stored in #resultatSP. (I don't know if it is conventional but it works), but I cannot reproduce it in MySQL.
I tried things like this:
MySQL code
drop temporary table if exists resultatSP;
create temporary table resultatSP (...);
...
resultatSP = CALL other_procedure(...);
OR
CALL other_procedure INSERT INTO resultatSP;
But nothing works.
I read that in MySQL, call stored procedure does not return result and we must use OUT/INOUT parameters. But I cannot change the other_procedure(...).
What is the most confusing is that this other_procedure has been convert in MySQL and it is used in java with some Javax.persistance annotations as #NamedNativeQuery or #SqlResultSetMapping and these annoations succeed to get the "result" of the last select of the stored procedure other_procedure(...) converted in MySQL. I don't know how these annotations make it.
I wrote a stored procedure (sp_archivev3) on MySQl Workbench which is as follows. Basically, Inserting values from one database to another.
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`MailMe`#`%` PROCEDURE `sp_archivev3`()
BEGIN
INSERT INTO
send.sgev3_archive(a_bi,
b_vc,
c_int,
d_int,
e_vc,
f_vc,
g_vc,
h_vc,
i_dt,
j_vc,
k_vc,
l_vc,
m_dt,
n_vch,
o_bit)
SELECT a_bi,
b_vc,
c_int,
d_int,
e_vc,
f_vc,
g_vc,
h_vc,
i_dt,
j_vc,
k_vc,
l_vc,
m_dt,
n_vch,
o_bit
FROM send.sgev3
WHERE m_dt BETWEEN '2014-06-09' AND CURDATE();
END
When I run call sp_archivev3(); , I get an error with an error code 1046: No database
selected SELECT the default DB to be used by double-clicking its name in the SCHEMAS list in the sidebar.
Please let me know what's wrong with my stored procedure.
The problem is that MySQL doesn't know which procedure named sp_archivev3 is supposed to be executed; MySQL doesn't know which database to look in. (Stored programs are objects in a specific database, just like tables are objects in a specific database.)
Either specify the current database with USE statement:
use mydatabase;
call sp_archivev3();
or qualify the procedure with the name of database:
call mydatabase.sp_archivev3();
I am unable to get the OUT parameter of a MySQL procedure call in the output stream with the procedure call step of Pentaho Kettle.
I'm having big trouble retrieving OUT parameter from MYSQL stored procedure to stream. I think it's maybe a kind of bug becouse it only occurs with Integer out parameter, it works with String out parameter. The exception I get is:
Invalid value for getLong() - '
I think the parameters are correctly set as you can see in the ktr.
You can replicate the bug in this way:
Schema
create schema if not exists test;
use test;
DROP PROCEDURE IF EXISTS procedure_test;
delimiter $$
CREATE PROCEDURE procedure_test(IN in_param INT UNSIGNED, OUT out_param INT UNSIGNED)
BEGIN
SET out_param := in_param;
END
$$
KTR
You can download here .ktr file with the steps. You just have to setup the connection to MySQL test schema to try it.
Other data
MySQL connector: 5.1.30
MySQL version: 5.5
Kettle version: 5.0.1-stable
OS: Ubuntu 12.04
Any help from the community will be highly appreciated.
Thanks in advance!
The bug does not seem to occur if number (and decimal at DB level) is used as the output parameter type. So this may be used as a work around.
With a DB procedure using this statement (as returned by phpMyAdmin):
CREATE DEFINER = `root`#`localhost`
PROCEDURE `procedure_test` ( IN `in_param` INT ZEROFILL,
OUT `out_param` DECIMAL( 10 ) )
NOT DETERMINISTIC NO SQL SQL SECURITY DEFINER
BEGIN
SET out_param =2 * in_param;
END
I was able to run this transformation
reading this input
IN_VALUE
1
2
3
99
yielding this output
<?xml version="1.0" encoding="UTF-8"?>
<Rows>
<Row><OUT_VALUE> 2,0</OUT_VALUE> </Row>
<Row><OUT_VALUE> 4,0</OUT_VALUE> </Row>
<Row><OUT_VALUE> 6,0</OUT_VALUE> </Row>
<Row><OUT_VALUE> 198,0</OUT_VALUE> </Row>
</Rows>
I have solved the problem using SQL script step with an SQL like this:
CALL procedure_test(?, #output_value);
INSERT INTO output_value_for(in, out) VALUES (?, #output_value);
SQL script step don't allow output value to stream, however it was a better solution for my problem. After procedure execution, I inserted in MySQL database output value of the procedure becouse I need to persist that relation.
However, I think Marcus answer is better approach for the posed problem. If you have this problem, you should take it into account as work around.
I'm using MySQL 5.5 (x64) and MySQL Workbench 5.2 deployed locally on a Windows 7 workstation for development purposes. I used MySQL Workbench to build a schema with the following function definition:
CREATE FUNCTION `db`.`get_public_name` (GPN_entID INT) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE GPN_pubName VARCHAR(64);
SELECT public_name INTO GPN_pubName
FROM entity WHERE id_entity=GPN_entID LIMIT 1;
RETURN GPN_pubName;
END
I then attempt to "Forward Engineer" the schema to the database with the following options specified:
DROP Objects Before Each Create Object
Generate DROP SCHEMA
Add SHOW WARNINGS After Every DDL Statement
GENERATE INSERT Statements for Tables
After this, MySQL Workbench attempts to publish to the server:
CREATE FUNCTION `db`.`get_public_name` (GPN_entID INT) RETURNS VARCHAR(64)
DETERMINISTIC
BEGIN
DECLARE GPN_pubName VARCHAR(64);
SELECT public_name FROM entity WHERE id_entity = GPN_entID;
RETURN GPN_pubName;
END
This results in the following error:
Executing SQL script in server
ERROR: Error 1415: Not allowed to return a result set from a function
Upon closer examination, I noticed the "INTO" and "LIMIT" clauses of the SELECT statement have been removed from the original function definition. This looks like it might be a cached version of the function, but I have tried everything I can think of (short of uninstalling and reinstalling MySQL Workbench) to flush any such cache to reload the correct version, but to no avail.
So, why is this change happening and how do I prevent it from happening?
Try changing to this:
SELECT public_name FROM entity WHERE id_entity = GPN_entID LIMIT 1 INTO GPN_pubName;
I'm embarrassed; if it wasn't for the fact this may be useful to others, I'd just go ahead and delete this question to hide my shame.
It turns out I created two functions with the same name and MySQL Workbench happily let me do so. I didn't notice that was the case until I started going through the stored routines with a more careful eye. I was editing one, but the other one (which had the error) was never changed. Since publishing each function involved dropping any earlier version from the database, I probably wouldn't have noticed this until things weren't working properly.
I am having a strange problem with MySQL Stored Procedure.
I have written a simple stored procedure as follows:
{
DELIMITER $$
CREATE DEFINER=`username`#`%` PROCEDURE `sp_create_my_log`(IN source TEXT,
OUT my_id INT)
BEGIN
--
-- insert record and return primary key
INSERT INTO my_log (source) VALUES (source);
SET my_id = LAST_INSERT_ID();
COMMIT;
END
}
This stored procedure is running absolutely fine on my local machine (MySQL Server 5.1, Windows XP). But when I try to run it on the server, I get the following error:
java.sql.SQLException: Parameter index of 2 is out of range (1, 0)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1075)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929)
at com.mysql.jdbc.CallableStatement$CallableStatementParamInfo.checkBounds(CallableStatement.java:274)
at com.mysql.jdbc.CallableStatement.checkParameterIndexBounds(CallableStatement.java:710)
at com.mysql.jdbc.CallableStatement.checkIsOutputParam(CallableStatement.java:672)
at com.mysql.jdbc.CallableStatement.registerOutParameter(CallableStatement.java:1846)
at org.apache.commons.dbcp.DelegatingCallableStatement.registerOutParameter(DelegatingCallableStatement.java:95)
at org.apache.commons.dbcp.DelegatingCallableStatement.registerOutParameter(DelegatingCallableStatement.java:95)
at com.mycomp.myprj.importer.ImporterImpl.onPreLoad(ImporterImpl.java:160)
at com.mycomp.myprj.importer.csv.FileImporter.load(FileImporter.java:43)
at com.mycomp.myprj.importer.csv.MyImporter.main(MyImporter.java:82)
0.843 seconds
Any idea why this is happening?
Just a wild guess (I'm more an Oracle than a MySQL kind of guy):
- Did you perhaps declare your parameter in Java wrong? (my_id is declared as an out parameter in the stored procedure, do the signatures in Java and MySQL match?)
- What happens if you call your procedure from the MySQL command line interface?
Kind regards, Frank