Why is SQLErrorCode zero? - postgresql

In my Java program I'm using JDBC to access my PostgreSQL database and that is running fine. Trying to catch SQLExceptions does not really work.
My code:
...
catch (SQLException se) {
System.out.println("\nSQLException: " + se.getMessage());
SqlErrorCode = se.getErrorCode();
System.out.println("\nSqlErrorCode: " + SqlErrorCode);
}
...
My query (generated by program):
SELECT osm_id, osm_type from (SELECT osm_dach_admin_boundaries_old.osm_id,
osm_dach_admin_boundaries_old.osm_type
FROM osm_dach_admin_boundaries_old
FULL OUTER JOIN osm_dach_admin_boundaries
ON (osm_dach_admin_boundaries_old.osm_id = osm_dach_admin_boundaries.osm_id
and osm_dach_admin_boundaries_old.osm_type = osm_dach_admin_boundaries.osm_type)
WHERE (osm_dach_admin_boundaries_old.osm_id IS NULL
OR osm_dach_admin_boundaries.osm_id IS NULL)) foo
WHERE osm_id is not null order by osm_id, osm_typeXXX;
Note the column osm_typeXXX, which I added to force an exception.
Running this query leads to
SQLException: ERROR: column "osm_typexxx" does not exist
Hinweis: Perhaps you meant to reference the column "foo.osm_type".
Position: 533
SqlErrorCode: 0
Closing source SQL-Connection
Closing destination SQL-Connection
Why is SqlErrorCode zero and how can I fix that?

java.sql.SQLException.getErrorCode() is documented as:
Retrieves the vendor-specific exception code for this SQLException object.
Now PostgreSQL doesn't have vendor-specific error codes – it uses the standard conforming SQLSTATE instead.
So you should use java.sql.SQLException.getSQLState().

Related

Check if pg_prepare was already executed

Is there a way to check if pg_prepare already executed and remove it from the session?
Seems like pg_close doesn't remove prepared statement from the session. Kind of seems like a bug in php, but maybe I'm missing something or maybe there is a workaround.
public static function readSubdomains($dcName, $filter = null) {
// ...
$conn = pg_pconnect($connectionString);
// ...
$result = pg_prepare($conn, "subdomains", "SELECT subdomain
from tenants
where $where
order by 1 asc
");
$result = pg_execute($conn, "subdomains", $params);
// ...
pg_close($conn);
}
Second call to readSubdomains shows a warning like this:
Warning: pg_prepare(): Query failed: ERROR: prepared expression "subdomains" already exists in inc/TestHelper.php on line 121
Always check the official manuals for this sort of stuff.
https://www.postgresql.org/docs/current/view-pg-prepared-statements.html
Oh - if pg_close isn't dropping prepared statements then it isn't closing the connection. You might have some connection pooling involved.

Not able to query for SQL ignore part of WHERE, if parameter is null

Hi iam able to get the data between the time ranges.
but if i specify OR :#{#orgSearch.createdTime.startDateTime} IS NULL then im getting exceptions
this is my #Query
#Query(value = "select o from Organization o where (o.createdAt >:#{#orgSearch.createdTime.startDateTime} OR :#{#orgSearch.createdTime.startDateTime} IS NULL) AND (o.createdAt <:#{#orgSearch.createdTime.endDateTime}) OR :#{#orgSearch.createdTime.endDateTime} IS NULL ")
but iam getting exceptions like below......
Caused by: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $2
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2103)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1836)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.jdbc.pool.StatementFacade$StatementProxy.invoke(StatementFacade.java:114)
at com.sun.proxy.$Proxy139.executeQuery(Unknown Source)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
... 95 more
any help Please?..
The solution is to force PostgreSQL to interpret the parameter as a timestamp.
Refer this query and make yours accordingly.
SELECT *
FROM log
WHERE CASE
WHEN $P{timestampFrom}::TIMESTAMP IS NULL THEN TIMESTAMP >= '-infinity'
ELSE TIMESTAMP >= $P{timestampFrom}
END
So, I tested this little workaround I mentioned earlier, and it works with the 5.0-5.3 type system. Assuming your timestamp class in Java is java.time.Instant, this can work
if (timestamps == null) {
query.setParameter("ts", java.time.Instant.EPOCH);
}
query.setParameter("ts", timestamp);
From then on your next problem comes from closing the round brackets before the OR over here:
... (o.createdAt <:#{#orgSearch.createdTime.endDateTime}) OR :#{#orgSearch.createdTime.endDateTime} IS NULL
This all assumes you create the query using entityManager.createNativeQuery(...) on your own, or possibly use a named native query, since those Spring-generated implementations can't add the workaround for you.
I've experienced this issue too with PostgreSQL and Instants.
The workaround I've used for this is to manually cast the parameter to timestamp
so if your query is like:
OR :#{#orgSearch.createdTime.endDateTime} IS NULL "
I'd try something like:
OR CAST(:#{#orgSearch.createdTime.endDateTime} AS TIMESTAMP) IS NULL "
Hope this helps

Postgres Aliasing [duplicate]

I have been able to link PostgreSQL to java. I have been able to display all the records in the table, however I unable to perform delete operation.
Here is my code:
con = DriverManager.getConnection(url, user, password);
String stm = "DELETE FROM hostdetails WHERE MAC = 'kzhdf'";
pst = con.prepareStatement(stm);
pst.executeUpdate();
Please note that MAC is a string field and is written in capital letters. This field does exist in the table.
The error that I am getting:
SEVERE: ERROR: column "mac" does not exist
When it comes to Postgresql and entity names (Tables, Columns, etc.) with UPPER CASE letters, you need to "escape" the word by placing it in "". Please refer to the documentation on this particular subject. So, your example would be written like this:
String stm = "DELETE FROM hostdetails WHERE \"MAC\" = 'kzhdf'";
On a side note, considering you are using prepared statements, you should not be setting the value directly in your SQL statement.
con = DriverManager.getConnection(url, user, password);
String stm = "DELETE FROM hostdetails WHERE \"MAC\" = ?";
pst = con.prepareStatement(stm);
pst.setString(1, "kzhdf");
pst.executeUpdate();

How to pass a null value received on msg.req.query to msg.payload

I am developing an application using Dashdb on Bluemix and nodered, my PHP application uses the call to webservice to invoke the node-red, whenever my function on PHP invokes the node to insert on table and the field GEO_ID is null, the application fails, I understand the issue, it seems the third parameter was not informed, I have just tried to check the param before and passing something like NULL but it continues not working.
See the code:
msg.account_id = msg.req.query.account_id;
msg.user_id = msg.req.query.user_id;
msg.geo_id=msg.req.query.geo_id;
msg.payload = "INSERT INTO ACCOUNT_USER (ACCOUNT_ID, USER_ID, GEO_ID) VALUES (?,?,?) ";
return msg;
And on Dashdb component I have set the parameter as below:
msg.account_id,msg.user_id,msg.geo_id
The third geo_id is the issue, I have tried something like the code below:
if(msg.req.query.geo_id===null){msg.geo_id=null}
or
if(msg.req.query.geo_id===null){msg.geo_id="null"}
The error I got is the one below:
dashDB query node: Error: [IBM][CLI Driver][DB2/LINUXX8664] SQL0420N Invalid character found in a character string argument of the function "DECIMAL". SQLSTATE=22018
I really appreciate if someone could help me on it .
Thanks,
Eduardo Diogo Garcia
Is it possible that msg.req.query.geo_id is set to an empty string?
In that case neither if statement above would get executed, and you would be trying to insert an empty string into a DECIMAL column. Maybe try something like this:
if (! msg.req.query.geo_id || msg.req.query.geo_id == '') {
msg.geo_id = null;
}

App hangs when executing the query in prepared statement

I am trying to select rows which are older than 7 days from current date. Database used is DB2 version 9.
Can you please tell me how exactly can I use the datetime in the query? The date table field is of type timestamp.
I am able to manually run the query without issues. However, when I am using in the prepared statement,
The app hangs when executing the query result = pselect.executeQuery(); as a result of which we need to restart db2 instance in order to clear it.
Can you please help what might be the issue? I do not see any exceptions at all. Other parts of the code works fine if I remove the select_query part.
try{
String select_query = "SELECT URL_ID ,URLVAL FROM URL_TAB WHERE " +
"UPDATED_DATE < TIMESTAMP(CURRENT_DATE - 7 DAYS, '00.00.00')";
System.out.println("select_query=" + select_query);
conn = JDBCDataObjectFactoryManager
.getConnection("JDBCConnectionFactory-SDE");
pselect = conn.prepareStatement(select_query);
System.out.println("pselect=" + pselect);
try{
System.out.println("inside try");
result = pselect.executeQuery();
System.out.println("result=" + result);
}catch(Exception e){
System.out.println("inside catch");
System.out.println("error message==============>"+e.getMessage());
}
if ((result != null) && (result.next())) {
System.out.println("3 >>>>>>>>>>>>>>>>>>>>>>>>>");
url_id = result.getInt(1);
url = result.getString(2);
}//end if
There are two possibilities: either the query is in a lock wait, or it runs for so long that it appears to be hung.
Check what is the value of LOCKWAIT database configuration parameter --by default it is -1, which means infinity, and you normally want to set it to a more reasonable value, typically 30 or 60 seconds. If it is the lock wait that causes your application to "hang", you would get an exception instead, which will help you to debug further.
If the issue is caused by the poor query performance, you'll need to work with your DBAs to figure out the root cause and resolve it.