hello I'm trying to execute mssql stored procedure from hibernate. Procedure has 8 input parameters and no output. But I get java.sql.SQLException: Parameter #9 has not been set whuli executing.
<sql-query name="insertMyData" callable="true">
{ ? = call InsertMyData(?,?,?,?,?,?,?,?) }
</sql-query>
Java invocation
Query query = m_entityManager.createNamedQuery("insertMyData");
query.setParameter(1, transaction.getGuid());
query.setParameter(2, new Date());
........ other parameters specified
Stored procedure
CREATE PROC dbo.insertMyData
#ID uniqueidentifier,
...... 7 more parameters
AS
BEGIN
INSERT INTO dbo.TestData VALUES (
#ID,
........ 7 more parameters
)
END
My bad with my earlier suggestion:
According to https://forum.hibernate.org/viewtopic.php?f=1&t=986612
Another person with the same issue, got it resolved by removing the "? =" since there was not 'return' defined for the quesry. I would suggest you try the same.
Hope this helps.
Seems like you have ignored the first ? and called setParameter only 8 times for the ? inside the procedure call.
This is how you should set your first parameter:
statement.registerOutParameter(1, Types.VARCHAR); //Assuming statement is your CallableStatement and return type of procedure is Varchar
Related
I am trying to execute a Stored Procedure which updates a column and retrieves the filename from the same table after updating
StoredProcedure:
CREATE DEFINER=`test`#`%` PROCEDURE `update_count`(
IN in_testID VARCHAR(64),
OUT out_FileName VARCHAR(100),
OUT out_Message VARCHAR(100))
BEGIN
UPDATE files SET count=count+1 WHERE testID=in_testID;
SELECT FileName INTO out_FileName FROM files WHERE testID = in_testID;
SET out_Message = 'File updated uccessfully';
END
JavaCode to execute this StoredProcedure:
Query query = session.createSQLQuery("CALL update_count(:in_testID, #out_FileName, #out_Message)").addEntity(FilesBean.class)
.setParameter("in_testID",body.getTestId());
query.executeUpdate();
Updated the query.executeUpdate() with query.list(). But the line returning a error ResultSet is from UPDATE. No Data
I need to fix this with using the createSQLQuery
The easiest way to do that is return the out parameter as part of the returning parameters (relevant only if you have access to the store procedures).
just add a store procedure like the following one
create procedure myProcedure_only_in_prams (
in in_Id int)
begin
call myProcedure(in_id,#out_Id) ;
select #out_id
END;
after done that it quite simple to use it with Hibernate in the following way
Query query = session.createSQLQuery(
"CALL myProcedure_only_in_parms (:in_Id)")
.setParameter("in_id", 123);
List result = query.list();
The result contains the out parameter, if you want return multiply parameters you can add it by doing select #parm1,#parm2,... ,#parmn
Hope it helped
I have a function I created in my PostgreSQL DB that I want to call using JPA 2.1's StoredProcedureQuery method.
Here is my PostgreSQL query:
CREATE OR REPLACE FUNCTION get_values(date text) returns refcursor
AS $$
DECLARE tuples refcursor;
BEGIN OPEN tuples FOR
SELECT user, COUNT(*)
FROM my_table
WHERE date_ = date
GROUP BY user;
return tuples;
END;
$$
LANGUAGE plpgsql
This is just a simple query to count users on a particular day. This is just a demo query to test how the StoredProcedureQueries work. And in fact, it works just fine when used via postgreSQL alone.
Now, let's try and call this using JPA 2.1 and in Javaland:
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.setParameter(2, "2015-02-01");
storedProcedure.execute();
When I do this, I get back the following exception:
org.hibernate.HibernateException: PostgreSQL supports only one REF_CURSOR parameter, but multiple were registered
There is only a single ref cursor declared! In fact, if I just register the single REF_CURSOR parameter and hardcode in a value for my Postgresql function for the WHERE date_ = date, this call works just fine.
So it would seem adding any additional parameters to a storedprocedurequery with a ref_cursor breaks the functionality. Alone, the ref_cursor parameters works fine.
Anybody see why this would happen?? Why is it that adding parameters to the StoredProcedureQuery for my PostgreSQL function breaks it?
Example of when it works:
CREATE OR REPLACE FUNCTION get_values(date text) returns refcursor
AS $$
DECLARE tuples refcursor;
BEGIN OPEN tuples FOR
SELECT user, COUNT(*)
FROM my_table
WHERE date_ = '2015-02-01'
GROUP BY user;
return tuples;
END;
$$
LANGUAGE plpgsql
and in javaland:
StoredProcedureQuery storedProcedure = em.createStoredProcedureQuery("get_values");
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.execute();
Short answer: Reverse the order of your two calls to registerStoredProcedureParameter():
storedProcedure.registerStoredProcedureParameter(1, Object.class, ParameterMode.REF_CURSOR);
storedProcedure.registerStoredProcedureParameter(2, String.class, ParameterMode.IN);
Long answer: I did some digging in the Hibernate source code for Postgress callable statement support, and found that each registerStoredProcedureParameter() call creates a ParameterRegistrationImplementor instance that gets tacked into a list and passed around. You'll note that this class stores the position of the parameter, which is independent of its position within the list.
Later, this list is analyzed and assumes that the REF_CURSOR parameter will be first in line, and throws your error message if a REF_CURSOR parameter is not first, regardless of what the parameter number is.
Not a very bright way of doing things (IMHO), but at least the workaround is easy: if you swap the order of your calls, you should be fine.
DELIMITER //
CREATE PROCEDURE temp ( empId INT)
BEGIN
DECLARE var_etype VARCHAR(36);
SELECT
emptype = QOUTE(emptype)
FROM
dms_document
WHERE
id = empid;
SELECT
emptype,
CASE
WHEN emptype = 'P' THEN doctype
ELSE 'No Documents required'
END
FROM
dms_report
WHERE
pilot = 1;
End//
DELIMITER ;
I have created this procedure successfully but when I try to call it, I am getting error 1305 the function database.temp does not exist. I am trying to call using this statement:
SET #increment = '1';
select temp( #increment)
but I get Error, please tell me where I made mistake.
This is how you call it, use use the keyword call and then procedure's name
call procedureName(params);
in call of making an string
String sqlString = "procedureName("+?+")"; //in case of Integers
String sqlString = "procedureName('"+?+"')";//in case of Integers
bring the parameter in prepared statement.
MySQL's documentation on Using JDBC CallableStatements to Execute Stored Procedures explains the necessary steps quite well.
This is what your java code needs to look like:
CallableStatement cStmt = conn.prepareCall("{call temp(?)}");
cStmt.setInt(1, 42); //set your input parameter, empId, to 42.
If you want to work with the rows returned by your stored procedure's query in your Java code, you're also going to need to create an OUT parameter as noted in MySql's documentation page titled, CALL Syntax:
CALL can pass back values to its caller using parameters that are
declared as OUT or INOUT parameters
In order to call your stored procedure from MySQL workbench, use the CALL command. You can call stored procedure by directly setting values for each of the parameters:
SET #increment = 1;
CALL temp(#increment)
Then you simply use the SELECT statement to return the value of your output parameter
SELECT #outParameter
With help setting your output parameters, please read the article MySQL Stored Procedure - SELECT - Example.
Your stored procedure is syntactically wrong, and as mentioned in the comments, you're not using the stored procedure functionality for it's intended use. It's intended to be used for data manipulation not for querying. You should instead consider turning your procedure into a series of prepared statements.
Please let me know if you have any questions!
I'm struck with an issue where am trying to call an Oracle stored procedure using Hibernate as in the below snippets.
My DAO class:
Query q = session.createSQLQuery(" {call PKG.PROC_GET_DATA_SET(?, :parameter1, :parameter2) }")
.setParameter(0, OracleTypes.CURSOR)
.setParameter("parameter1", "fDate")
.setParameter("parameter2", "tDate");
resultSet = q.list();
PROCEDURE:
CREATE OR REPLACE PACKAGE BODY schema.PKG
AS
PROCEDURE PROC_GET_DATA_SET(
P_CURSOR OUT SYS_REFCURSOR,
P_STRING1 IN VARCHAR2,
P_STRING2 IN VARCHAR2
)
AS
BEGIN
OPEN P_CURSOR FOR
.
.
.
But when i call the proc as in the DAO class, am getting an error as below.
Error:
PLS-00306: wrong number or types of arguments in call to 'PROC_GET_DATA_SET'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Struggling to spot the reason. Can someone throw some light here please?
TIA,
You cannot use this code to call a procedure using hibernate. See docs
The recommended call form is standard SQL92: { ? = call
functionName() } or { ? = call
procedureName(}. Native call syntax is not supported.
For Oracle the following rules apply:
A function must return a result set. The first parameter of a
procedure must be an OUT that returns a result set. This is done by
using a SYS_REFCURSOR type in Oracle 9 or 10. In Oracle you need to
define a REF CURSOR type. See Oracle literature for further
information.
I suggest trying this:
{? = call PKG.PROC_GET_DATA_SET(?, ?) }
If this does not work, use session.connection()
I am getting an Error while running this:
1. cs = getCon1().prepareCall("{CALL SaveLabourWageDetails(?,?)}");
2. cs.setString(1, user.getUserId());
3. cs.registerOutParameter(2, java.sql.Types.INTEGER); //<--- ERROR at this line
4. cs.execute();
5. String lastIsertId=cs.getString(2);
The Stored Procedure is :
CREATE
PROCEDURE `cheque_alert`.`SaveLabourDetailsHead`(IN wage_entered_by VARCHAR(10),OUT LastInsertId INT)
BEGIN
INSERT INTO `cheque_alert`.`labour_wage_head`
(
`wage_entered_by`,
`entered_date_time`)
VALUES (wage_entered_by,
NOW());
SELECT LAST_INSERT_ID() INTO LastInsertId;
END$$
DELIMITER ;
Please point out the problem in this code..
You are calling wrong procedure. You have procedure SaveLabourDetailsHead and you are calling
1. cs = getCon1().prepareCall("{CALL SaveLabourWageDetails(?,?)}");
↑
Change to,
1. cs = getCon1().prepareCall("{CALL SaveLabourDetailsHead(?)}");
Set String parameter wage_entered_by.
Your out parameter is of type String, but it should be int. Try this out.
int lastIsertId=cs.getInt(2);
I had the same problem but the output exception is misleading as the root cause was the procedure name.
I typed incorrect procedure which did not exist in database.
Instead of providing a SQL exception something like "routine does not exist", it gave:
java.sql.SQLException: Parameter number 2 is not an OUT parameter.
Just had the same problem.
It was a permission issue in my case. The MySQL user my application uses lacked the EXECUTE permission on the schema I'm working on.
GRANT EXECUTE ON <your_schema>.* TO '<your_user>'#'localhost';
FLUSH PRIVILEGES;