PostgreSQL MAX aggregate function applied to strings and Java resultset - java

Hello and thank you for reading my post.
I have a PostgreSQL table "t" with a column "c" which type is "character varying(32)".
Values in this column look like this: "2014100605".
I am using the "MAX()" aggregate function to retrieve the maximum value in this column.
SELECT MAX(c) AS max FROM t;
In Java, if I prepare the query above, get a "resultSet" object and send it the getString("max") message, I get max = null.
If I send it the getInt("max") method instead, I get the result I'm expecting, something like "2014100605".
Is this normal behavior?
Am I really allowed to do this or is it by chance I'm getting the expected result?
Is "MAX()" actually using the lexicographical order?
Best regards.
A bit of Java code:
s_preparedSqlQuery =
"SELECT MAX(quotinv_nro) AS quotinv_nro_max "
+ "FROM imw_quotation_invoice "
+ "WHERE quotinv_type = ? "
+ "AND quotinv_nro LIKE '" + s_quotinvDate + "%'";
preparedStatement = m_connection.prepareStatement(s_preparedSqlQuery);
preparedStatement.setString(1, s_quotinvType);
resultSet = preparedStatement.executeQuery();
if(resultSet != null)
{
if(resultSet.next())
{
// s_quotinvNroMax = resultSet.getString("quotinv_nro_max");
n_quotinvNroMax = resultSet.getInt("quotinv_nro_max");
// if(s_quotinvNroMax == null)
if(n_quotinvNroMax == 0)
{
n_nbQuotinvsThisSameDate = 0;
return n_nbQuotinvsThisSameDate;
}
else
{
s_quotinvNroMax = Integer.toString(n_quotinvNroMax);
n_length = s_quotinvDate.length();
s_currentMaxNro = s_quotinvNroMax.substring(n_length - 1);
n_nbQuotinvsThisSameDate = Integer.valueOf(s_currentMaxNro);
}
}
}

If you are hitting on a unique Id column....
int maxID = 0;
Statement s2 = con.createStatement();
s2.execute("SELECT MAX(UniqueId) FROM MyTable");
ResultSet rs2 = s2.getResultSet();
if (rs2.next())
{
maxID = rs2.getInt(1);
}
If you are hitting on any other non-key column....
int maxID = 0;
Statement s2 = con.createStatement();
s2.execute("SELECT MAX(ColumnValue) FROM MyTable");
ResultSet rs2 = s2.getResultSet();
while (rs2.next())
{
maxID = rs2.getInt(1);
}

Related

how to solve operation is not allowed for result set type FORWARD_ONLY?

I have this method in a class trying to read from a DB in HANA to insert in oracle:
private void selectZ_ITEM_MASTER() {
//System.out.println("entre al select");
try {
Statement stmt;
ResultSet rs = null;
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName(getHec_driver());
ds.setUrl(getHec_url());
ds.setUsername(getHec_usuario());
ds.setPassword(getHec_clave());
ds.setMaxActive(-1);
Connection con = ds.getConnection();
stmt = con.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
String query = "SELECT ";
query += "MARA.MANDT, ";
query += "MARC.WERKS, ";
query += "MARA.MATNR, ";
query += "MAKT.MAKTX, ";
query += "MAKT.MAKTG, ";
query += "MARA.MATKL, ";
query += "T023T.WGBEZ, ";
query += "T023T.WGBEZ60, ";
query += "MARA.BRGEW, ";
query += "MARA.NTGEW, ";
query += "MARA.GEWEI, ";
query += "MARA.MEINS, ";
query += "MARA.SPART, ";
query += "TSPAT.VTEXT ";
query += "FROM ";
query += "SAPR3P.MARA MARA LEFT OUTER JOIN SAPR3P.MAKT MAKT ON MARA.MANDT = MAKT.MANDT AND ";
query += " MARA.MATNR = MAKT.MATNR ";
query += " LEFT OUTER JOIN SAPR3P.T023T T023T ON MARA.MANDT = T023T.MANDT AND ";
query += " MARA.MATKL = T023T.MATKL AND ";
query += " T023T.SPRAS = 'S' ";
query += " LEFT OUTER JOIN SAPR3P.TSPAT TSPAT ON MARA.MANDT = TSPAT.MANDT AND ";
query += " MARA.SPART = TSPAT.SPART AND ";
query += " TSPAT.SPRAS = 'S' ";
query += " LEFT OUTER JOIN SAPR3P.MARC MARC ON MARA.MANDT = MARC.MANDT AND ";
query += " MARA.MATNR = MARC.MATNR ";
query += "WHERE ";
query += "MARA.MANDT = '100' ";
//query += "AND MARC.WERKS IN ('3000') ";
//query += "AND MARA.MATNR IN ('000000004030005209','000000004030005215')";
query += "AND MARC.WERKS IN ('1000','2000') ";
query += "AND MARA.MATNR BETWEEN '000000001000000152' AND '000000001000000152' ";
query += "ORDER BY ";
query += "MARA.MANDT, MARC.WERKS, ";
query += "MARA.MATNR ";
//System.out.println(query);
try{
rs = stmt.executeQuery(query);
rows = 1;
rs.last();
rows = rs.getRow();
System.out.println("Cantidad de Registros:" + rows);
ResultSetMetaData rsmd = rs.getMetaData();
columns = rsmd.getColumnCount();
System.out.println("Cantidad de Columnas:" +columns);
arr = new String[rows][columns];
int i = 0;
rs.beforeFirst();
while (rs.next()){
for (int j = 0; j < columns; j++)
arr [i][j] = rs.getString(j+1);
i++;
}
} catch (SQLException e) {
e.printStackTrace();
insertLog("Z_ITEM_MASTER VEN: " + e.getMessage(),"error", "Z_ITEM_MASTER VEN");
}
stmt.close();
con.close();
rs.close();
} catch (Exception e) {
e.printStackTrace();
msj = e.getMessage();
insertLog("Z_ITEM_MASTER VEN: " + e.getMessage(),"error", "Z_ITEM_MASTER VEN");
}
}
I was getting an error with use CONCUR_READ_ONLY, CONCUR_UPDATABLE and I managed to solved it by researching about Invalid argument result Set Concurrency, but now I'm having another issue and I'm kind of stuck. this is the error msg:
com.sap.db.jdbc.exceptions.JDBCDriverException: SAP DBTech JDBC: The operation is not allowed for result set type FORWARD_ONLY.
at com.sap.db.jdbc.exceptions.SQLExceptionSapDB.createException(SQLExceptionSapDB.java:345)
at com.sap.db.jdbc.exceptions.SQLExceptionSapDB.generateSQLException(SQLExceptionSapDB.java:113)
at com.sap.db.jdbc.ResultSetSapDB.assertNotForwardOnly(ResultSetSapDB.java:2760)
at com.sap.db.jdbc.ResultSetSapDB.last(ResultSetSapDB.java:592)
at com.sap.db.jdbc.trace.ResultSet.last(ResultSet.java:972)
at org.apache.commons.dbcp.DelegatingResultSet.last(DelegatingResultSet.java:367)
at org.apache.commons.dbcp.DelegatingResultSet.last(DelegatingResultSet.java:367)
at org.inverpaca.integracion.Integracion.selectZ_ITEM_MASTER(Integracion.java:145)
at org.inverpaca.integracion.Integracion.insertDatos(Integracion.java:207)
at org.inverpaca.integracion.Integracion.main(Integracion.java:287)
can someone help me?
some forums refer to this problems having something to do with the statements setting to the correct result set or something like that.
With the forward-only cursor, you cannot jump to the end to get the number of records and then jump back to iterate through the result set.
You seem to use this information only to size the array that you want to put the result set into. There are better ways to do that, e.g. Storing Result set into an array.
Besides that, you might want to check with your license teams, whether or not you are actually licensed to access the SAP data like this. Direct database access on the base tables of the data model comes with many restrictions as you by-pass the whole application level security model.

java.sql.SQLSyntaxErrorException: ORA-01795: maximum number of expressions in a list is 1000

we all know we see this exception when try to bomabard the query with more than 1000 values. the maximum for the column limit is 1000.. the best possible solution is to split the query into two.guys can u suggest some possible ways of code refactoring to make my problem go away.any help would be appreciated.
we see the exception when audTypeFieldIdList are greater than 1000 values.
try {
String query = "select AUDIT_TYPE_FIELD_ID, FIELD_NAME from AUDIT_TYPE_FIELD where AUDIT_TYPE_FIELD_ID in (";
int x = 0;
for (int y = 1; y <= audTypeFieldIdList.size(); y++) {
query += audTypeFieldIdList.get(x);
if (y != audTypeFieldIdList.size()) {
query += ", ";
}
x++;
}
query += ")";
List<Long> audTypeFieldIdList, Connection connection) {
ResultSet rs = null;
Statement stmt = null;
List<AuditTypeField> audTypeFieldList = new ArrayList<AuditTypeField>();
try {
String query = "select AUDIT_TYPE_FIELD_ID, FIELD_NAME from AUDIT_TYPE_FIELD where AUDIT_TYPE_FIELD_ID in (";
int x = 0;
for (int y = 1; y <= audTypeFieldIdList.size(); y++) {
query += audTypeFieldIdList.get(x);
if (y != audTypeFieldIdList.size()) {
query += ", ";
}
x++;
}
query += ")";
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
while (rs != null && rs.next()) {
AuditTypeField audTypeField = PluginSystem.INSTANCE
.getPluginInjector().getInstance(AuditTypeField.class);
audTypeField.setId(rs.getLong("AUDIT_TYPE_FIELD_ID"));
audTypeField.setName(rs.getString("FIELD_NAME"));
audTypeFieldList.add(audTypeField);
}
return audTypeFieldList;
return audTypeFieldList;
You can't use more than 1000 entries in IN clause. There are 2 solutions as mentioned below:
Use inner query to solve this issue. You can create a temporary table and use that in your IN clause.
Break it in the batch of 1000 entries using multiple IN clause separated by OR clause.
sample query:
select * from table_name
where
column_name in (V1,V2,V3,...V1000)
or
column_name in (V1001,V1002,V1003,...V2000)
...
Read more.. and see Oracle FAQ

MySQLSyntaxErrorException when setting strings

I have a strange problem. When I execute the query in the following piece of code it throws a MySQLSyntaxErrorException with the message:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near
''fantasy' SET Quantity = 3 WHERE BookName = 'The Silmarilion'' at line 1
Code:
private void updateDBTable(String category, Vector dataVector) {
try {
for(int i = 0; i < dataVector.size(); i++) {
String bookName = String.valueOf(((Vector) dataVector.elementAt(i))
.elementAt(0));
int quantity = (int) ((Vector) dataVector.elementAt(i))
.elementAt(4);
statement = databaseConnection
.prepareStatement("UPDATE ? SET Quantity = ? WHERE BookName = ?");
statement.setString(1, category);
statement.setInt(2, quantity);
statement.setString(3, bookName);
statement.executeUpdate();
}
}
But if I write it in this way :
private void updateDBTable(String category, Vector dataVector) {
try {
for(int i = 0; i < dataVector.size(); i++) {
String bookName = String.valueOf(((Vector) dataVector.elementAt(i))
.elementAt(0));
bookName = "'" + bookName + "'";
int quantity = (int) ((Vector) dataVector.elementAt(i))
.elementAt(4);
statement = databaseConnection
.prepareStatement("UPDATE " +
category +
" SET Quantity = ? WHERE BookName = " +
bookName);
statement.setInt(1, quantity);
statement.executeUpdate();
}
}
It works fine. Can you help me to figure out why the syntax in the first example is wrong?
In the first case, you have also provided the table name as a parameter. Prepared statements take the column names as parameters. You need to provide the table name in the statement while using prepareStatement

prepare statement is not succesful in case of query is having subQuery

i am using below simple query to get the result for testing purpose.
qName = "select total_requests from (select 10000 as total_requests from dual)"; //this can be dynamic query
preStatement = connection.prepareStatement(qName);
ParameterMetaData pmd = preStatement.getParameterMetaData();
int stmtCount = pmd.getParameterCount();
int paramsCount = params == null ? 0 : params.length;
for (int i = 0; i < params.length; i++) {
if (params[i] != null) {
preStatement.setObject(i + 1, params[i]);
} else {
int sqlType = Types.VARCHAR;
if (!paramValid) {
try {
sqlType = pmd.getParameterType(i + 1);
} catch (SQLException e) {
paramValid = true;
}
}
preStatement.setNull(i + 1, sqlType);
}
}
ResultSet rs = preStatement.executeQuery();
once i am executing 3rd line, below error is thrown by application
Caused by: java.lang.AbstractMethodError: com.inet.pool.b.getParameterMetaData()Ljava/sql/ParameterMetaData;
at com.core.admin.util.AnalyzeHelper.fillQuery(AnalyzeHelper.java:61)
is this due to subQuery issue?
how to resolve this?
use this for executing query
preStatement.executeQuery();
you need to have a result set for viewing
ResultSet rs=preStatement.executeQuery();
while(rs.next())
{
rs.getString(1);// I assume that first column is a String.If it is an INT then use rs.getInt(1);
//similarly for other columns
}
It may helps you.
qName = "select total_requests from (select 10000 as total_requests from dual)";
preStatement = connection.prepareStatement(qName);
ResultSet rs= preStatement.executeQuery();

count similar rows of one table in jdbc

I'm trying to count same values from one column of the table and return the value and counter, for example: value 1 repeat 3 time, value 2 repeat 2 time, ...
So far my program can store all value of desired column in an array. My problem is I don't know how to compare each value with other value. I know I need a counter and maybe one more array. So I stuck in If condition.
try{
Statement stmt = conn.createStatement();
//Statement stmt1 = conn.createStatement();
ResultSet rset = stmt.executeQuery( "SELECT N_REGIONKEY FROM NATION " );
List N_REGIONKEY = new ArrayList ();
while (rset.next()){
N_REGIONKEY.add(rset.getInt("N_REGIONKEY"));
if (rset.next ==N_REGIONKEY){
.
.
.
}
//System.out.println(N_REGIONKEY);
}
}
This is new version of what I wrote with your help, still the answer is not what it should be..
try{
System.out.println("counting rows in NATION table");
Statement stmt = conn.createStatement();
// Statement stmt1 = conn.createStatement();
ResultSet rset = stmt.executeQuery( "SELECT N_REGIONKEY FROM NATION " );
ArrayList N_REGIONKEY = new ArrayList ();
while (rset.next()){
N_REGIONKEY.add(rset.getInt("N_REGIONKEY"));
int occurrences = 0;
for (int i = 0; i<N_REGIONKEY.size();i++)
{
occurrences = Collections.frequency(N_REGIONKEY,N_REGIONKEY.get(i) );
System.out.println("There is " + occurrences + "occurrences for " + N_REGIONKEY.get(i));
}
Try to count by sql query, not by array
select N_REGIONKEY, count(N_REGIONKEY) as 'COUNT'
FROM NATION
group by N_REGIONKEY
int occurrences = 0;
for (int i = 0; i<N_REGIONKEY.size();i++){
occurrences = Collections.frequency(REGIONKEY, REGIONKEY.get(i));
System.out.println("There is " + ocurrences "ocurrences for " + N_RegionKey.get(i));
}
Thanks every one for your helps.Finally, I wrote this program without group by(even-though I know it's much slower). This ones has the same result as with "group by".
try{
System.out.println("counting simillar rows in NATION table");
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery( "SELECT N_REGIONKEY FROM NATION " );
ArrayList N_REGIONKEY = new ArrayList ();
int[] MyCounter = new int[5];
while (rset.next()){
MyCounter[rset.getInt("N_REGIONKEY")] ++;
}
for (int i = 0; i<5;i++){
if (MyCounter[i] > 0) {
System.out.println("There is " + MyCounter[i] + " ocurrences for " + i);
}

Categories