Getting ERROR: cursor "<unnamed portal 1>" does not exist - java

Im trying to use SimpleJdbcCall from spring.jdbc calling function that return a cursor and im getting following error:
org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{? = call dbo.api_config_select(?)}]; SQL state [34000]; error code [0]; ERROR: cursor "<unnamed portal 1>" does not exist; nested exception is org.postgresql.util.PSQLException: ERROR: cursor "<unnamed portal 1>" does not exist
This is PostGreSQL function code:
CREATE OR REPLACE FUNCTION "dbo"."api_config_select" (in "_id" integer) RETURNS refcursor AS
$$
DECLARE
ref refcursor;
BEGIN
OPEN ref FOR
SELECT
1;
RETURN ref;
END;
$$
LANGUAGE 'plpgsql' COST 100
and this is Java code
simpleJdbcCall = new SimpleJdbcCall(jdbcTemplate).withFunctionName("api_config_select").withSchemaName("dbo")
.declareParameters(
new SqlOutParameter("_cursor", Types.OTHER),
new SqlParameter("_id", Types.INTEGER));
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("_id", id);
try {
Map<String, Object> result = simpleJdbcCall.execute(10);
for (String s : result.keySet()) {
System.out.println("6.0 " + result.get(s));
}
}
catch(UncategorizedSQLException e) {
e.printStackTrace();
}
catch(Exception e) {
e.printStackTrace();
}
As soon as app call simpleJdbcCall.execute() im getting error. I tried to pass refcursor name, but getting same error.
Anyone have code sample code of using PostgreSql, Spring JDBC and cursor?

use this code block in your method :
Connection conn = jdbcTemplate.getDataSource().getConnection();
conn.setAutoCommit(false);
CallableStatement proc = conn.prepareCall("{? = call dbo.api_config_select() }");
proc.registerOutParameter(1, Types.OTHER);
proc.execute();
ResultSet results = (ResultSet) proc.getObject(1);
while (results.next())
{
// do something with the results.
}
results.close();
proc.close();

Make sure that you must have use
connection.setAutoCommit(false);
just after the connection check as below:
if (connection != null) {
connection.setAutoCommit(false);
Reason is if you will not use setAutoCommit(false), cursor will be close and while retrieving the data it will fail.

Related

jdbc PSQLException: ERROR: syntax error at or near "CONFLICT"

I'm trying to update a table in my postgres DB with JDBC, and for most of my queries it works just fine. But sometime I get this error:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "CONFLICT"
When I do the request manually in postgres it works just fine:
INSERT INTO user_jira (key_user,account_id,name_user,email_adress,display_name,active)
VALUES ('admin','5a283eThisIsJustAnExample','admin','john.john#proceedit.com','john john',true)
ON CONFLICT (key_user)
DO UPDATE
SET account_id=excluded.account_id,
name_user=excluded.name_user,
email_adress=excluded.email_adress,
display_name=excluded.display_name,
active=excluded.active;
Does anyone konws whats going on?
Edit: here is how I connect to the db and send my query:
String url = "jdbc:postgresql://host:port/db";//connect(url);
Properties props = new Properties();
props.setProperty("user","user");
props.setProperty("password","*********");
try {
dyDATAconn = DriverManager.getConnection(url, props);
System.out.println("connected to "+url);
Statement st;
//sql statement
st = dyDATAconn.createStatement();
int userRowInserted = st.executeUpdate(User.sqlUpdate(newUser));
int taskRowInserted = st.executeUpdate(Task.sqlUpdate(allTask));
int timeSpentRowInserted = st.executeUpdate(TimeSpent.sqlUpdate(allTimeSpent));
System.out.println("tsk: "+taskRowInserted+"\nTS:"+timeSpentRowInserted);
} catch (SQLException e) {
System.out.println("connection to dyJIRA#dyDATA failed");
System.out.println(User.sqlUpdate(newUser));
e.printStackTrace();
return -1;
}
I can't show how I create my query, but I only got pb with users and the requests are all the same format as the one above

How to reuse connect function database java mysqlite?

I'm writing an application with java form and sqlite and I have a function to connect to database and get data like this:
public ResultSet getResultSet(String query) {
Connection conn = null;
ResultSet rs = null;
try {
// create a database conn
conn = DriverManager.getConnection("jdbc:sqlite:C:\\Users\\nguye_000\\Desktop\\qlct.db");
Statement statement = conn.createStatement();
statement.setQueryTimeout(30);
rs = statement.executeQuery(query);
return rs;
}
catch(SQLException e) {
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally {
try {
if(conn != null)
conn.close();
}
catch(SQLException e) {
// conn close failed.
System.err.println(e);
}
}
return rs;
}
Why when I call it in main function I get an error?
Database db = new Database();
ResultSet rs = db.getResultSet("SELECT * FROM qlct_options");
while(rs.next()) {
// read the result set
System.out.println("id = " + rs.getInt("option_id"));
System.out.println("name = " + rs.getString("option_key"));
System.out.println("value = " + rs.getString("option_value"));
}
id = 0
name = null
value = null
Exception in thread "main" java.sql.SQLException: [SQLITE_MISUSE] Library used incorrectly (out of memory)
at org.sqlite.core.DB.newSQLException(DB.java:890)
at org.sqlite.core.DB.newSQLException(DB.java:901)
at org.sqlite.core.DB.throwex(DB.java:868)
at org.sqlite.jdbc3.JDBC3ResultSet.next(JDBC3ResultSet.java:83)
at qlct.Qlct.main(Qlct.java:18)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)
I want to everytime run a any query I can use getResultSet() function and pass query into it. I can't write a code like this http://chuoidichvu.com/downloads/Database.java, each time I need to write a query I do try{} catch{}, final{}. It's hard!
You return a ResultSet from your function after having close the connection (in the finally part of the outer try).
This causes an error, since you can scan the ResultSet only while the Statement and the Connection are still open.
To obtain your objective (“reuse connect function database java mysqlite”) you have to “rearrange” the abstraction that you are trying to define. For instance you could pass to your method a lambda expression (if you are using Java 8) that processes the result inside it.

Java PreparedStatement autogenerated keys SQLException

I am trying to get the autogenerated key from my SQL Insert preparedstatement from an oracle database. I have tried mimicking every example I could find and I always get a SQLException from the .executeUpdate() call. I am certain this works fine without the second argument in the prepareStatement() call so it is not the SQL itself. Please what am I doing wrong?
I am getting the error:
I seem to be getting this: [1/19/15 0:50:50:462 EST] 00000054
ConnectionEve A J2CA0056I: The Connection Manager received a fatal
connection error from the Resource Adapter for resource[extracted]. The
exception which was received is
com.ibm.websphere.ce.cm.StaleConnectionException: Protocol
violation:java.sql.SQLException: Protocol violation
the code goes like this
Connection conSOX = AggIOTraceUtil.getJNDISOXConnection(JNDIConn);
PreparedStatement preparedStatement = null;
String sii_agg_id = null;
if (conSOX != null)
{
preparedStatement = conSOX.prepareStatement(SII_SOX_APP_QUERY, new String[] { "SII_TASK_AGG_STATUS_ID" });
preparedStatement.setObject(1, traceObject.getTaskName());
preparedStatement.setObject(2, traceObject.getTaskType());
preparedStatement.setObject(3, traceObject.getSpTaskStartedDate());
ETC ETC ...
preparedStatement.executeUpdate();
// Get the auto generated aggregation ID
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
if (null != generatedKeys && generatedKeys.next()) {
log.error("Hello");
sii_agg_id = generatedKeys.getString(1);
log.error("SII AGG ID = " + sii_agg_id);
My SQL query is:
private static final String SII_SOX_APP_QUERY = "insert into
SII_TASK_AGG_STATUS(SII_TASK_AGG_STATUS_ID, DATA_AGG_TASK_NAME,
"+ "TASK_TYPE, TASK_STARTED_DATE, TASK_COMPLETED_DATE, TASK_LAUNCHED_DATE,
APP_SCANNED, "+ "EXTRA_ENTITLEMENT_CHANGES, IDENTITIES_UPDATED,
LINKS_OR_GROUPS_DELETED, GROUPS_UPDATED, " + "IDENTITIES_CREATED,
GROUPS_CREATED, TASK_MESSAGE, COLUMN_NAMES, DELIMITER, LINE_SKIPPED,
"+ "LOGICAL_APP_NAME, IS_PRIMARY_TIER, AGG_STATUS, DATA_AGG_AUDIT_ID,
SII_TASK_STATUS_ID" + ")
values(SII_TASK_AGG_STATUS_SEQ.NEXTVAL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
?,?,?,?,?,?)";

SQLServerException: A result set was generated for update

I'm trying to insert a new record into an MS SQL database, and I'm getting an exception I've never seen before. When I call executeUpdate the following exception is thrown:
com.microsoft.sqlserver.jdbc.SQLServerException: A result set was generated for update.
This is the Java code that produces the error:
// addComment method adds a new comment for a given requestId
public CommentBean addComment(CommentBean comment) {
PreparedStatement stmt = null;
INative nat = null;
Connection conn = null;
try {
nat = dbConn.retrieveNative();
conn = (Connection)nat.getNative("java.sql.Connection");
stmt = conn.prepareStatement(ADD_COMMENT);
stmt.setInt(1, comment.getRequestId());
stmt.setString(2, comment.getComment());
stmt.setString(3, new SimpleDateFormat("MM/dd/yyyy").format(comment.getDateCreated()));
stmt.setString(4, comment.getCreatedBy());
comment.setCommentId(stmt.executeUpdate()); // exception
} catch(Exception ex) {
System.err.println("ProjectRegistration::SQLDAO - addComment");
ex.printStackTrace();
} finally {
try {
if (stmt != null) stmt.close();
} catch (Exception e) {}
}
return comment;
}// end addComment
Where ADD_COMMENT is defined as a String:
private static final String ADD_COMMENT = "INSERT INTO RequestComments OUTPUT INSERTED.commentId VALUES(?,?,?,?)";
For the sake of being thorough, the table is defined as:
CREATE TABLE RequestComments (
commentId int NOT NULL PRIMARY KEY IDENTITY(1,1),
requestId int FOREIGN KEY REFERENCES Requests(requestId),
comment varchar(400),
dateCreated date,
createdBy varchar(12)
);
I don't think I'm doing anything terribly complicated here, but I can't think of why I'm getting this exception. I have a method in the same class which does the exact same type of insertion (literally the same query with a different table name and number of values), and it has no issues. Does anyone have any ideas on how to resolve this issue?
This particular error can also be caused by an INSERT-trigger, which has a SELECT-statement as a part of the trigger code.
To test whether this is the case, you can try:
using executeQuery(), instead of executeUpdate() - and display the result.
executing the insert in tool like MySQL Workbench, SQL Server Management Studio, or whatever flavour of database design tools are available for your DBMS, to see whether a result is returned.
Related: sql server error "A result set was generated for update"
I'm hoping this may help others looking at the same error message, as it did for me. My solution was to live with a call to executeQuery(), although it only handles an underlying issue, instead of fixing it.
This instruction stmt.executeUpdate() is not returning the commentId, it returns a ResultSet which you could then get the commentId from. Something like this,
ResultSet rs = stmt.executeQuery(); // Not update, you're returning a ResultSet.
if (rs.next()) {
comment.setCommentId(rs.getInt(1));
}
you are using OUTPUT in your insert query i.e you will get a resultset after your query executes and to hold that you need an object of class ResultSet to hold that data
SqlServer : When SET NOCOUNT is ON, the count is not returned. When SET NOCOUNT is OFF, the count is returned.
Connection conn = DriverManager.getConnection(connectDB,user,pwd);
String sql = " set nocount off;INSERT INTO test (name) values (1)";
PreparedStatement prepareStatement = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
System.out.println(prepareStatement.executeUpdate());
ResultSet generatedKeys = prepareStatement.getGeneratedKeys();
if(generatedKeys.next()){
System.out.println(generatedKeys.getString(1));
}
Related:
set-nocount-on-usage
I've had a similar problem where after a while an insert on a autonumber table would give a "A result set was generated for update." at random. I use connection pooling and somehow the driver can get into a state where executeUpdate in combination with Statement.RETURN_GENERATED_KEYS doesn't work anymore. I found out that in this state an executeQuery does the trick, but in the initial state executeQuery does not work. This lead me to the following workaround:
PreparedStatement psInsert = connection.prepareStatement("INSERT INTO XYZ (A,B,C) VALUES(?,?,?)", Statement.RETURN_GENERATED_KEYS);
ResultSet rs = null;
try {
psInsert.setString(1, "A");
psInsert.setString(2, "B");
psInsert.setString(3, "C");
Savepoint savePoint = connection.setSavepoint();
try {
psInsert.executeUpdate();
rs = psInsert.getGeneratedKeys();
} catch (SQLServerException sqe)
{
if (!sqe.getMessage().equals("A result set was generated for update."))
throw sqe;
connection.rollback(savePoint);
rs = psInsert.executeQuery();
}
rs.next();
idField = rs.getInt(1);
} finally {
if(rs != null)
rs.close();
psInsert.close();
}

java.sql.SQLException: Exhausted Resultset error

I'm facing the problem with this exception java.sql.SQLException: Exhausted Resultset in following code. I'm sure my query returns only one value. Even If I don't use rs.next(); it throws the error java.sql.SQLException: ResultSet.next was not called. Could you please help?
FYI, I'm using the another result set in main where this menthod from another class is called. will it affect?
Thanks
public static String getdispname(Connection conn, String resname)
throws SQLException, Exception {
//String resname = "";
String returnValue = "";
String querystring = "";
//Query to select the displayname from resid
querystring += "select distinct display_name";
querystring += " from cust_rally_team_member";
querystring += " where display_name like '%"+ resid +"%'";
// Create select statement
Statement stmt = conn.createStatement();
try {
// Execute statement
ResultSet rs = stmt.executeQuery(querystring);
if (rs!= null) {
while (rs.next()) {
returnValue = rs.getString("display_name");
} catch (SQLException ex) {
throw new SQLException(ex);
} catch (Exception ex) {
throw new Exception(ex);
}
// Close statement
finally {
stmt.close();
}
return returnValue;
Try as
if (rs! = null) {
while (rs.next()) {
returnValue = rs.getString("display_name");
}
......
Try:
returnValue = rs.next() ? rs.getString("display_name") : null;
You don't need to check if the rs is null. It won't be - assuming the executeQuery() returned rather than raising an exception. (Though the returned result set might have 0 rows).
You also don't need to loop over the result set, assuming you really know that you expect back a single row. (Though, given the query, that seems unlikely.)
use by your modification like below
if (rs != null && rs.first()) {
do {
returnValue = rs.getString(("display_name");
} while (rs.next());
}
I am using Oracle 10g database , i found same error "java.sql.SQLException: Exhausted Resultset error". I just grant permission in database and solved my probblem.
SQL> grant insert,update,delete on "table-name" to "database_name";

Categories

Resources