I am trying to insert into a db that I have, and I'd like to do so through parameters. I am connecting to a postgres db using java.
I can connect to the db just fine. I know that because I have various operations that I am using that are already working were I can see, and update existing rows in my db. I am having trouble with INSERT.
I have the following:
private String _update_rentals = "INSERT into rentals (cid, mid) values (?,?)";
private PreparedStatement _update_rentals_statement;
private String _update_movie_status = "UPDATE Movie SET checkedout = true WHERE mid = ?";
private PreparedStatement _update_movie_status_statement;
And I initialize them:
_update_movie_status_statement = _customer_db.prepareStatement(_update_movie_status);
_update_rentals_statement = _customer_db.prepareStatement(_update_rentals);
And
while (movieAvail.next()){
System.out.println(movieAvail.getBoolean(1));
if (movieAvail.getBoolean(1) == false){
//Do chekcout
_update_rentals_statement.clearParameters();
_update_rentals_statement.setInt(1, cid);
_update_rentals_statement.setInt(2, mid);
_update_rentals_statement.executeQuery();
_update_movie_status_statement.clearParameters();
_update_movie_status_statement.setInt(1, mid);
_update_movie_status_statement.executeQuery();
System.out.println("Enjoy your movie!");
}
}
I am getting an error with both of the executeQuery() calls. For some reason I am getting the following error with both:
Exception in thread "main" org.postgresql.util.PSQLException: No results were returned by the query.
I looked at other posts, and I believed that I was following syntax for both insert/ update correctly, so maybe I am overlooking some aspect of this.
This is all part of a larger code base, so I did not want to include the methods these pieces of code are in. But these are the isolated instances which play a part with this code.
In general, when you execute a query, you are willing to retrieve some kind of information from the database. This is usually the case when you are executing SELECT queries. However, with INSERT and UPDATE statements, you are not querying the database, you are simply executing an update or inserting new rows. In the documentation of PreparedStatement you can see in which cases an exception is being thrown when you try to call executeQuery:
Throws: SQLException - if a database access error occurs; this method
is called on a closed PreparedStatement or the SQL statement does not
return a ResultSet object
So in your case the problem is that your statements do not return a ResultSet. You should use execute or executeUpdate instead. The former simply executes the update, while the latter does the same, but also returns the number of affected rows.
I think the main issue is that you are calling executeQuery(), which expects a result to be returned, but Insert/Update are not queries and don't return a result. Try just calling execute().
Related
Im trying to get some returning data from an postgresql update. The "update" works well in the DB script, but in java I'm having some issues: the code stucks while executing the query.
I'm trying with "PreparedStatament ps", "ResultSet rs=ps.executeQuery" and "if(rs.next)" to get the data from the "returning" in the query, but it appears that the code didnt get in there, because it stuck exactly in the "ps.executeQuery".
Here's more or less what I'm trying to do:
String cVal="";
ps=myConn.prepareStatement("UPDATE someTable SET aValue=? WHERE bValue=?
returning Cvalue");
ps.setInt(1,"aNewValue");
ps.setInt(2,"aID");
rs=ps.executeQuery();
if (rs.next()){
cVal=rs.GetString("Cvalue");
return true;
}else{
return false;
}
I'm trying to set the values of "RETURNING" to some variables. There are 4 results that I want to set.
Since you are trying to update, in case of PreparedStatement, you have to use executeUpdate() method.
To know more details about methods in Statement and PreparedStatment, check below the
https://docs.oracle.com/javase/8/docs/api/java/sql/PreparedStatement.html#executeUpdate--
You can refer below an example.
https://www.mkyong.com/jdbc/jdbc-preparestatement-example-update-a-record/
First execute the update statement with ps.executeUpdate (), which returns the integer 0 or 1. The value indicates whether the update statement has executed or not. After that, execute the select query to get the updated data.
I have a stored procedure in a postgres database. I'm using the postgres JDBC driver to execute a stored procedure, and I do not care about the return type, and can't execute the query. It's indicating that there's a syntax error near the name of the function.
In procedures that return rows, I've been able to do this via a PreparedStatement and setting the parameters, like:
PreparedStatement prepared = connection.prepareStatement("SELECT * FROM NonQueryProcedure(?)");
prepared.setInt(1, 999);
// ....
ResulSet resultSet = prepared.executeQuery();
However, I can't seem to get this to work for an "update" stored procedure where I don't care about the return type. I've tried using connection.prepareStatement() and prepareCall(), and also tried executing it with statement.execute(), .executeUpdate(), and .executeQuery(), without success.
How can I execute a stored procedure where I don't care about the return type?
As PostgreSQL has no "real" procedures, functions are simply executed using a SELECT statement:
statement.execute("select NonQueryProcedure(?)");
Note that inside a PL/pgSQL function, you can use the perform statement to call such a function. But this is not available outside of a PL/pgSQL block.
Without the actual syntax error, I can't say for sure, but try this:
"SELECT * FROM \"getData\"(?)"
CamelCase/PascalCase is a BAD idea in any SQL database. Either it folds it to a single case and all you see is AMASSOFUNREADABLELETTERS or it requires quoting and you will have to forevermore type "aMassofLettersAndQuotesAndShiftKeysAndMyFingersHurt" anytime you want to avoid a syntax error.
I have come across a strange behavior while executing a SELECT query using Statement#executeUpdate() by mistake. While the Javadoc clearly states that executeUpdate() throws SQLException if the given SQL statement produces a ResultSet object. But when I'm executing SELECT * from TABLE_NAME, I don't get any exception. Instead I'm getting an return value which is same as the no. of rows selected, if no. is less than or equal to 10. If the no. is more than 10, the return value is always 10.
Connection conn;
Statement stmt;
try {
conn = getConnection();
stmt = conn.createStatement();
int count = stmt.executeUpdate("SELECT * from TABLE_NAME");
log.info("row count: " + count);
} catch (SQLException e) {
log.error(e);
// handle exception
} finally {
DbUtils.closeQuietly(stmt);
DbUtils.closeQuietly(conn);
}
I am using Oracle 10g.
Am I missing something here or is it up to the drivers to define their own behavior?
This behaviour is definetely contradicts Statement.executeUpdate API. What's interesting,
java.sql.Driver.jdbcCompliant API says "A driver may only report true here if it passes the JDBC compliance tests". I tested oracle.jdbc.OracleDriver.jdbcCompliant - it returns true. I also tested com.mysql.jdbc.Driver.jdbcCompliant - it returns false. But in the same situation as you describe it throws
Exception in thread "main" java.sql.SQLException: Can not issue SELECT via executeUpdate().
It seems that JDBC drivers are unpredictable.
According to the specifications Statement.executeUpdate() method returns the row count for SQL Data Manipulation Language (DML).
UPD: I attempted to make an assumption about the returned result (which is always <=10). It seems, that the oracle statement's implementation returns here a number of a such called premature batch count (according to the decompiled sources OraclePreparedStatement class). This is somehow linked to the update statements. May be this value equals 10 by default.
UPD-2: According to this: Performance Extensions: The premature batch flush count is summed to the return value of the next executeUpdate() or sendBatch() method.
The query you are using doesn't produce a ResultSet but affects Rows obviously. That's why you don't get an SQLException but a count of the no of rows affected. The mystery is why it doesn't go beyond 10. May it is Oracle JDBC Driver Implementation Specific.
Your sql query is to retrieve all rows from table_name. So, you can use execute() method instead of executeUpdate() method. Because later method generally use when your task is related database manipulating language like update query.
use
int count = stmt.executeQuery("SELECT * from TABLE_NAME");
instead of
int count = stmt.executeUpdate("SELECT * from TABLE_NAME");
for getting total no. of rows.
How to make query like this in Java and get the results:
SELECT filedata.num,st_area(ST_Difference(ST_TRANSFORM(filedata.the_geom,70066),filedata_temp.the_geom))
FROM filedata, filedata_temp
Where filedata.num=filedata_temp.num
Or, I think will be better if I create procedure in Postgres from this query.
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS void AS
$$
BEGIN
SELECT filedata.num,st_area(ST_Difference(ST_TRANSFORM(filedata.the_geom,70066),filedata_temp.the_geom))
FROM filedata, filedata_temp
Where filedata.num=filedata_temp.num
end;
$$
LANGUAGE 'plpgsql'
and call it
Connection ce_proc= null;
ce_proc = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgis","postgres","123456");
java.sql.CallableStatement proc = ce_proc.prepareCall("{get_geom_difference()}");
proc.execute();
proc.close();
ce_proc.close();
But how to get results from this procedure in Java?
UPDATE
I tried this SP
DROP FUNCTION get_geom_difference();
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS integer AS
$$
DECLARE
tt integer;
BEGIN
SELECT filedata.num INTO tt
FROM filedata
Where filedata.num=1;
RETURN tt;
END;
$$
LANGUAGE 'plpgsql'
and call
Class.forName("org.postgresql.Driver");
Connection connect= null;
connect = DriverManager.getConnection("jdbc:postgresql://localhost:5432/postgis","postgres","123456");
java.sql.CallableStatement proc = connect.prepareCall("{?=call get_geom_difference()}");
proc.registerOutParameter(1, java.sql.Types.INTEGER);
proc.executeQuery();
ResultSet results = (ResultSet) proc.getObject(1);
and got an error:
org.apache.jasper.JasperException: An exception occurred processing
JSP page /commit_changes.jsp at line 25in lineproc.executeQuery();
root cause javax.servlet.ServletException:
org.postgresql.util.PSQLException: No results were returned by the
query
But query
SELECT filedata.num
FROM filedata
Where filedata.num=1;
returns 1.
Where is mistake?
You can largely simplify the function. (Keeping simplistic function for the sake of the question.)
CREATE OR REPLACE FUNCTION get_geom_difference()
RETURNS integer AS
$BODY$
SELECT num
FROM filedata
WHERE num = 1
LIMIT 1; -- needed if there can be more than one rows with num = 1
$BODY$ LANGUAGE SQL;
Though, technically, what you have in the question would work, too - provided the data type matches. Does it? Is the column filedata.num of type integer? That's what I gather from the example. On your other question I was assumingnumeric for lack of information. At least one of them will fail.
If the return type of the function doesn't match the returned value you get an error from the PostgreSQL function. Properly configured, your PostgreSQL log would have detailed error messages in this case.
What do you see, when you create the above function in PostgreSQL and then call:
SELECT get_geom_difference(1);
from psql. (Preferably in the same session to rule out a mixup of databases, ports, servers or users.)
Calling a simple function taking one parameter and returning one scalar value seems pretty straight forward. Chapter 6.1 of the PostgreSQL JDBC manual has a full example which seems to agree perfectly with what you have in your question (My expertise is with Postgres rather than JDBC, though).
There are quite a few different CallableStatement constructors, but only two of them let you get results back.
A ResultSet is returned by CallableStatement.executeQuery(). There's a good complete example in the link above.
I don't know if getting a scalar result back from a CallableStatement is legal. I'd expect PgJDBC to translate it to a rowset of one row, though, so it should work.
Your query example is typical. So what you will need is
Java Database Connectivity (JDBC)
and everything needed to serv it, is in package java.sql
So at this point I recoemnd you to read some tutorial and if you have some particular problem write about it on SO.
You will need JDBC to do that. You should be able to find all JDBC related information here.
Take a look here for a more detailed tutorial on how to connect your Java application to your PostgreSQL.
works 100% java 7 and postgres pgadmin 2016, Use createNativeQuery In your transaction write this
and change myschema.mymethodThatReturnASelect
for the scheme and the name of your function.
#Override
public List<ViewFormulario> listarFormulario(Long idUsuario) {
List<ViewFormulario> list =null;
try {
Query q = em.createNativeQuery("SELECT * FROM myschema.mymethodThatReturnASelect(?);");
q.setParameter(1, idUsuario);
List<Object[]> listObject = (List<Object[]>) q.getResultList();
if (listObject != null && !listObject.isEmpty()) {
list = new ArrayList<>();
for (Object o[] : listObject) {
ViewFormulario c = new ViewFormulario();
c.setIdProyecto(o[0] != null ? Long.valueOf(o[0].toString()) : -1L);
...etc...etc.
I have been messing with Oracle DB queries that run from my JAVA app. I can successfully get them all to run in SQL Developer. But when I am trying to execute them from my JAVA app I usually get UpdatadbleResultSet Error/Exception on certain queries.
Also, sometimes I receive, ExhaustedResultset. As I mention at the bottom I will re work the question to break it down(When I get a chance). I keep editing and pretty soon it'll be a book.
Why is this? I cannot seem to pinpoint the problem.
Some queries run successfully such as:
SELECT table_name
FROM all_tables
SELECT column_name, data_length
FROM all_tab_columns
WHERE table_name = 'mytable'
But when I try and run something like
SELECT length(<myColumnName>)
FROM mytable
I get the updateableResultSetError
I am running my queries as methods called on button clicks (example below).
static void testQuery() {
String query = "SELECT blah from blah"
String length;
ResultSet rs = db.runQuery(query);
Length = rs.getString("length(myCol)")
System.out.println(length);
}
I have also tried while rs.next()
I can only think that for some reason I am unable to get into each table and I can only pull the "bigger" picture.
EDIT: Explained DB Connection
I am connecting using some other jarfiles that have been added to my project.
private static IDriver driver = null;
private static Database db = null;
I then pass in all my connection credentials in a separate method.
private void connectDB(){
driver = new OracleDriver();
db = new Database(driver)
driver.getPassword;
driver.getetc;
driver.getEtc;
}
EDIT:
When I getstacktrace all I am returning is.
Ljava.lang.StatckTraceElement;(assortment of random characters).
I may not be getting stack traces right so someone can fill me in. After all I am offering a bounty.
Also I will edit this question and break it down again when I have the time.
Your problem is that you're trying to update a query that can't be updated, hence the updateable result error. It seems that whoever is creating your database connection or executing your query is creating an updatable result set.
You can't use certain types of select in an updatable result set: you can't use aggregated functions (such as length, min, max), you can't use select * etc.)
For the full list see Result Set Limitations and Downgrade Rules
Try retrieving the value in your select statement via the columnIndex instead of the column name and see if that makes a difference.
Currently, its hard to tell what your db.runQuery() does since that code is not posted.
String query = "SELECT length(myCol) FROM myTable";
String length;
ResultSet rs = db.runQuery(query);
while (rs.next()) {
length = rs.getString(1);
System.out.println(length);
}
I've got an inkling what may be happening here (which would explain why some queries work, and some don't). Accoring to the jdbc ResultSet javadocs, when using the getString() method of the result set, the column label.
the label for the column specified with the SQL AS clause.
If the SQL AS clause was not specified, then the label is the name of the column
As "length(myCol)" is neither a label nor a column name, it may be that it fell over because of that (but without stacktrace it is difficult to say what your problem actually is).
Try
String query = "SELECT length(myCol) AS myCol_len FROM myTable"
ResultSet rs = db.runQuery(query);
String length = rs.getString("myCol_len");
Though are you sure, you didn't want:
int length = rs.getInt("myCol_len");
Alternatively (as written by Kal), you can use the column index to get the data from the result set, which oblivates the need for a SQL AS label:
String query = "SELECT length(myCol) FROM myTable"
ResultSet rs = db.runQuery(query);
String length = rs.getString(1);