I have a stored proc in SQL Server 2005, which looks like the following (simplified)
CREATE PROCEDURE FOO
#PARAMS
AS
BEGIN
-- STEP 1: POPULATE tmp_table
DECLARE #tmp_table TABLE (...)
INSERT INTO #tmp_table
SELECT * FROM BAR
-- STEP 2: USE #tmp_table FOR FINAL SELECT
SELECT abc, pqr
FROM BAZ JOIN #tmp_table
ON some_criteria
END
When I run this proc from SQL Server Management Studio, things work fine. However, when I call the same proc from a Java program, using something like:
cs = connection.prepareCall("exec proc ?,");
cs.setParam(...);
rs = cs.getResultSet(); // BOOM - Null!
while(rs.next()) {...} // NPE!
I fail to understand why the first result set returned is NULL. Can someone explain this to me?
As a workaround, if I check cs.getMoreResults() and if true, try another getResultSet() - THIS time it returns the proper result set.
Any pointers please? (I'm using JTDS drivers, if it matters)
Thanks,
Raj
The Javadoc for getResultSet() says that it returns null "... if the result is an update count or there are no more results". It looks like your stored procedure would have an update count and a resultset, and that the getResultSet() method is (arguably) just doing what the API contract says it should do.
You could try retrieving the update count first. Otherwise, stick with your "workaround".
Kind of pointless posting an answer after the correct answer has been selected I guess.
The solution I suggest is calling
set nocount on
before the insert statement and
set nocount off
afterwards. Inserts return a resultset otherwise.
Related
I am dealing with a legacy code that is 'not changeable' (no way to move to criteria api) and I have a little trouble with proper parameters binding. The query looks like this (MS SQL):
SELECT BRAND AS b FROM CAR WHERE (NAME LIKE :phrase OR MODEL LIKE :phrase ) AND AGE NOT IN(1997, 1998) AND (:mileage IS NULL OR MILEAGE LIKE :mileage) ORDER BY BRAND
(...)
query.setParameter("phrase", "%" + phrase + "%");
query.setParameter("mileage", mileage);
phrase is actually required, but because the mileageparameter is optional, it's done in wierd way presented above.
The problem is that with both phrase and mileage provided, It keeps giving me following error : java.sql.SQLException: ResultSet may only be accessed in a forward direction.. It works wihtout mileage parameter provided. Why I am getting this error ?
EDITED:
Running this query on db gives me no results.
I am using query.setResultTransformer(Transformers.aliasToBean(type)) as well as setting first and max result on my SQLQuery query object.
An error is when calling query.list() (used intellij evaluate expression)
shouldn't query.list() return an empty result ?
Probable answer (in that case):
It looks like setting FirstResult on the query cause that problem because - by mistake - it's a negative number.
How are you executing the SQL and then accessing the results?
It sounds like there are no results when executing the SQL with the mileage parameter and you are somehow trying to read the results anyway.
Try running the generated SQL immediately on the database and see if it returns any rows.
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 am trying to get value from a Table_X . But those table values inserted by a procedure. I am calling procedure like ps.execute() and i would like to wait until it ends and get all results from Table_X , everything looks like working. But it only returns a few results from Table_X not all. So I think it doesn't wait until procedure ends. So it only returns some inserted values.
How can I fix it ?
Edit : Codes ;
CallableStatement pstmt = con.prepareCall("{ ? = call "+job.getSP()+" }");
pstmt.registerOutParameter(1, Types.INTEGER);
pstmt.execute();
Then I am calling a method
Map<String,String> errors = MTRCMtdJob.GetDataControlErrors();
Those method gets value from Table_X
I presume there is only one issue, the transaction isolation level is allowing dirty reads even before the procedure transaction is committed. I recommend that you put the reading the table section in a new transaction block by using commit after the procedure transaction. And also please check the transaction isolation level.
I have table called mpi which contains 23 columns. I have introduced the search field with button for every column where user can enter the query to fetch the records using query
query="select * from mpi where Genus ='"+genus+"'
Now I want to fetch records by giving keywords using LIKE %% but it is not working and not giving any records but if type type the full name it is working perfectly. Here is the code
String uname=request.getParameter("uname");
String full="%"+uname+"%";
dbconn=new DatabaseConnection();
conn=dbconn.setConnection();
pstmt=conn.prepareStatement("select * from mpi where Genus LIKE ?");
pstmt.setString(1, full);
res=pstmt.executeQuery
Could any one tell me where is the mistake and why I am not getting the records when I use half keyword like %keyword%.
It works (apart from the missing parentheses) and the approach with a prepared statement is entirely correct.
However I have seen a couple of code pieces like that, and always the problem lay with variables mix-up or not closing, or simple oversight. Better declare as close as possible.
try (ResultSet res = pstmt.executeQuery()) {
while (res.next()) {
..
}
} // Automatically closes res.
Also handle the life-cycle of pstmt correctly, with closing.
I was not too long ago studying java, so maybe I have a stupid question.
I have a table, where i store some info.
And i want to check in this table on availability of some information (it will be only one line), and if yes - take from this line, the information in a particular column, if no - do another thing.
I really don`t know how to do this.
My idea was something like this: at first - check the table:
SELECT * FROM tablename WHERE nickname = "kvant";
then if true, do another query with searching info.
and do this with condition if\else. but all my attempts not turn.
I hope for your help, sorry for my awry English.
Check if the data exists like this:
IF EXISTS(SELECT * FROM tablename WHERE nickname = "kvant")
BEGIN
--value is found so go ahead
END
ELSE
--value not found
BEGIN
END
One simple way is to query the database and get the result. If result!=Null {//do something} else {//Do something}
(Can use try - catch as well)
Pure java possible solution:
Try to get that value in the query. Get the ResultSet rs of that query and:
if(rs.next()) {
String value = rs.getString("value"); //Assuming the column is value and that it is a String.
//Do whatever you want with the value
} else {
//The other thing
}
If you can not take the value from the first ResultSet, do another query in the if.
write in sql like select case exists (select * from yourtable where condition) then 'dothis thing' else 'dootherthing' from 'yourtable' where 'yourcondition'
since you wanted to run some other query after you know you have some conditon exists.