Get PostgreSql table size on disk (byte) in ORMlite - java

I use ORMLite in a Java application, in order to deal with a PostgreSql DataBase.
I want to get the space on the disc used by a table of DataBase.
It seems that OrmLite doesn't have a specific method to get it, so I tried without success:
final String TABLE_NAME = "a_table_name_of_db";
//1)
String SQL = "SELECT pg_relation_size('" + TABLE_NAME + "');" ;
int result = OGGETTO_DAO.executeRaw(SQL);
//2)
String SQL = "SELECT pg_table_size('" + TABLE_NAME + "');" ;
int result = OGGETTO_DAO.executeRaw(SQL);
//3 - it was just a try...)
SQL = "SELECT pg_table_size('" + TABLE_NAME + "');" ;
GenericRawResults<String> ARRAY = OGGETTO_DAO.queryRaw(SQL);
String result= ARRAY.getFirstResult();
With 1) and 2) I get always -1, with 3) I get a cast exception;
I I use the command 'pg_relation_size' or 'pg_table_size' by command line (linux - by psql prompt), it works properly.
What am I wrong?
Thank you
UPDATE - WORKING SOLUTION:
Now it works! Solution, as per accepted answer below, is:
final String TABLE_NAME = "a_table_name_of_db";
String SQL = "SELECT pg_table_size('" + TABLE_NAME + "');"
final long RESULT = OGGETTO_DAO.queryRawValue(SQL); //in bytes

int result = OGGETTO_DAO.executeRaw(SQL);
Yeah that's not right. Looking at the javadocs for executeRaw(...) they say that it returns the number of rows affected not the result.
SQL = "SELECT pg_table_size('" + TABLE_NAME + "');" ;
GenericRawResults ARRAY = OGGETTO_DAO.queryRaw(SQL);
String result= ARRAY.getFirstResult();
Looking at the javadocs for queryRaw(...), the problem here is it returns a GenericRawResults<String[]> and not <String>. It returns a collection of raw results, each row being represented by a string array. I'm really surprised that your code even compiles.
It should be:
GenericRawResults<String[]> ARRAY = OGGETTO_DAO.queryRaw(SQL);
String result= ARRAY.getFirstResult()[0];
Probably the best way to do this is to use queryRawValue(...) which performs a raw query and returns a single value.
// throws an exception if there are no results or if the first one isn't a number
long size = OGGETTO_DAO.queryRawValue(SQL);

Related

NamedParameterJdbcTemplate not updating when using batchUpdate

I have a list of objects provided by another service which I use to update my own data. When I try to use NamedParameterJdbcTemplate.batchUpdate, all returned values are zero.
public void updateWeather(List<Weather> weatherList) {
String query = "UPDATE weather \n" +
"SET rain_probability = ROUND(:rainProbability, 4), \n" +
"wind_speed = :windSpeed \n" +
"WHERE city_id = :cityId AND date = :date;";
List<MapSqlParameterSource> batchList = new ArrayList<>();
for(Weather weather : weatherList) {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("rainProbability", weather.getRainProbability());
params.addValue("windSpeed", weather.getWindSpeed());
params.addValue("cityId", weather.getCityId());
params.addValue("date", weather.getDate());
batchList.add(params);
}
this.namedParameterJdbcParameter
.batchUpdate(query, batchList.toArray(new MapSqlParameterSource[] {});
}
If I run this UPDATE directly in the database, it works fine. Futhermore, if I run it one by one, that is, replacing values (instead of adding the parameter source to batchList) it also works.
For example:
for (Weather weather : weatherList) {
String query = String.format("UPDATE weather \n" +
"SET rain_probability = ROUND('%d', 4), \n" +
" wind_speed = %d \n" +
" WHERE city_id = :cityId AND date = :date;",
weather.getRainProbability(),
weather.getWindSpeed(),
weather.getCityId(),
weather.getDate()
);
this.namedParameterJdbcTemplate.update(query, Collections.emptyMap());
}
Any suggestions of what I'm doing wrong?
Is it the use of "\n" or the ";" at the end of the statement within the String? (I'm surprised you don't get a SQL Syntax exception with the ; inside the actual query string)
Also dates are always a bit tricky and if that isn't converting properly then your WHERE clause isn't going to match and is possibly why 0 rows are returned. Could you temporarily try converting dates to Strings and see if the count is correct (e.g. for Oracle: AND date = TO_DATE(:dateStr, 'DD/MM/YYYY') )

how to update a db value

I have a mysql database here I have columns for oldNominalValue and newNominalValue. I have 12 rounds in which at the each end of the round I update my new and nominal values. At the end of each round I need to set my newnominalvalue to oldnominalvalue how can I do this. Can anyone please tell me how to do this. Thanks for your time.
String CMF= rs.getString("comapanyName");
String ONV = rs.getString("oldNominalValue");
String NNV = rs.getString("newNominalValue");
// String NS = rs.getString("numberOfShares");
// System.out.print(CMF);
nominalvalue = Integer.parseInt(ONV);
//int nv = 1;
T = randNum / 100;
RT = T * nominalvalue;
newnominalvalue = nominalvalue - RT;
st = con.createStatement();
String query08= "update where " + FS + " (comapanyName,newnominalValue,oldNominalValue,PLock) VALUE ('" + gameName + "','Financial','" + CMF + "',', " + newnominalvalue + "," + nominalvalue + "', 0 )";
st.executeUpdate(query08);
Are you familiar with SQL syntax? There are some issues with your update query. Also, try using a prepared statement instead of a regular statement when using parameters and use proper resource management (ensure the statement gets closed again). See the sample below:
String statement = "UPDATE <your-table> SET newnominalValue = ?, oldNominalValue = ? WHERE <your-id-column> = ?";
try(PreparedStatement updateStmt = con.prepareStatement(statement)) {
updateStmt.setString(1, NNV);
updateStmt.setString(2, ONV);
updateStmt.setString(3, FS); // not sure what FS is in your code, or what type it is
updateStmt.executeUpdate();
}
Also, please use sensible and camelCased names in Java, it will help you and others in the long run to maintain the code. Variable names like 'T', 'RT' and 'FS' are most likely to confuse people and makes things a lot harder.

Sql2o keep returning a same set of data although query is different

I am new to using SQL2O with MySQL, but I am having a weird problem, where different queries return same results. Is SQL2O returning me cached results?
My code looks like this:
String sql = "SELECT * " +
"FROM report_A" +
"ORDER BY :order :sequence "+
"LIMIT :from, :limit";
int limit = 5;
int startIndex = (page-1)*limit;
String sequence = "DESC";
try(Connection con = sql2o.open()) {
if(order.contains("-")){
order = order.replace("-", "");
sequence= " ASC";
}
Query query= con.createQuery(sql)
.addParameter("from", startIndex)
.addParameter("limit", limit)
.addParameter("order", order)
.addParameter("sequence", sequence);
List<ReportA> result = query.executeAndFetch(ReportA.class);
con.close();
The 4 parameters always change, but the output remains the same. I have verified the queries in mysql workbench, the data is different, but SQL2O returns me the same set of data. Am I missing something?
Your query is invalid. It wont compile and throw an Sql2oException on execution.
The problem is, basically, that you can use parameters only for values, not for table names, column names or other keywords like "ASC". Changing those would change the structure of the query.
It's possible to construct queries with variable structure by good old string concatenation, i.e.
String sql = "SELECT * " +
"FROM report_A" +
"ORDER BY " + order " " + SEQUENCE +
"LIMIT :from, :limit";
and then
query(sql)
.addParameter("from", from)
.addParameter("limit", limit)
.executeAndFetch(...)

UCanAccess data exception: numeric value out of range

I have a table called [Elenco_Aziende] from which I extract all the record in a resultset. [Elenco_Aziende] is in a relation one to many with other two tables called [Elenco_Autisti] and [Elenco_Veicoli] via a field called [Partita_IVA_Azienda] that is also primary key in [Elenco_Aziende] table.
After extracting all records from [Elenco_Aziende] I perform a loop for each value of [Partita_IVA_Azienda] and then open a new result set to try to read values in related fields of [Elenco_Autisti] and [Elenco_Veicoli] tables and do for each of them some operation.
And here comes strange thing: As long as [Partita_IVA_Azienda] (which is defined as a Text field in the Access DB) values are all the same length everything is OK when I try to read in [Elenco_Autisti] and [Elenco_Veicoli] tables, but if some of [Partita_IVA_Azienda] has a different length then I got error:
net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.1 data exception: numeric value out of range
More precisely here is the nested loop scenario:
Connection con = DriverManager.getConnection("jdbc:ucanaccess://"
+ filepath);
String qry = "SELECT * FROM Elenco_Aziende";
ResultSet rs = stmt.executeQuery(qry);
String cognometest = "";
String nometest ="";
while (rs.next()) {
String partitaiva = "Partita IVA: "
+ rs.getString("Partita_IVA_Azienda") + "\n\r";
String partitaivazienda = rs.getString("Partita_IVA_Azienda");
Statement stmtautisti = con.createStatement();
System.out.println("Sto per eseguire la query per partita iva azienda = " + partitaivazienda + "\n\r");
String qryautisti = "SELECT * FROM Elenco_Autisti WHERE Partita_IVA_Azienda="
+ partitaivazienda; /*!!!!! AND HERE WHEN I EXECUTE NEXT QUERY IS WHERE I GET THE EXCEPTION net.ucanaccess.jdbc.UcanaccessSQLException: UCAExc:::3.0.1 data exception: numeric value out of range more!!!!!*/
ResultSet rsautisti = stmtautisti.executeQuery(qryautisti);
while (rsautisti.next()) {
do something here
}
Statement stmtveicoli = con.createStatement();
String qryveicoli = "SELECT * FROM Elenco_Veicoli WHERE Partita_IVA_Azienda="
+ rs.getString("Partita_IVA_Azienda");
ResultSet rsveicoli = stmtveicoli.executeQuery(qryveicoli);
while (rsveicoli.next()) {
do something else here
}
that is as soon as I execute the query
String qryautisti = "SELECT * FROM Elenco_Autisti WHERE Partita_IVA_Azienda="+ partitaivazienda;
for a different length value of [Partita_IVA_Azienda] I get the problem.
I even tried to export the database in a comma separated value and reimporting it in a brand new one but it did not help. Furthermore, the problem seems to happen just for large number of records in tables [Elenco_Autisti] (138 records) and [Elenco_Veicoli] (287 records), while seems not to happen for small number of records. [Elenco_Aziende] is small (no more than 10 records).
According to the little of what I know about SQL, a WHERE with a text field should be written with the value in apostrophes:
String qryautisti = "SELECT * FROM Elenco_Autisti WHERE Partita_IVA_Azienda='"
+ partitaivazienda + "'";

How to modify SQL-Statement?

I have a problem that i canĀ“t solve :(
I execute this sql statement to get the max of a the CCID-String:
"select MAX(CCID) as test123 from "
+ tabelleName+ " where CCID like 'W%'");
After that I want to increase the string. I substring the W and convert the string to an int:
String ccid = rs.getString("test123");
String test = ccid.substring(1,6);
int id = Integer.parseInt(test);
int newid = id+1;
At the moment the max(ccid) looks like W01352.
The result of newid is "1353" without the "W0".
I want to get a string like W01353 that I could add to the db2-database for the next W-Number.
Do someone have any idea?
Sorry for my not so perfect english ;)
Thank u.
Maybe you can take a look at the db2 substring function : http://publib.boulder.ibm.com/infocenter/dzichelp/v2r2/index.jsp?topic=%2Fcom.ibm.db2z9.doc.sqlref%2Fsrc%2Ftpc%2Fdb2z_bif_substring.htm
You can try select substring(MAX(CCID), 2, x) as test123 from ..
where x is the type you want: CODEUNITS16, CODEUNITS32, ..
This should return the value without the W0
edit
to add leading zero's to the new integer, do the following:
String old = "W01234";
String sub = old.substring(1); // "01234"
Integer id = Integer.parse(sub); //1234
Integer newI = id + 1; // 1235
String newS = "W" + ("00000" + newI).substring(newI.toString().length()); // "W01235"
Use PreparedStatement rather that Statement, eaiser and efficient way to work the SQL queries.
String sql = "select MAX(CCID) as test123 from <tabelleName> where CCID like '?%'");
PreparedStatement preparedStatement = dbConnection.prepareStatement(sql);
preparedStatement.setString(1, "...");
ResultSet rs = preparedStatement.executeQuery(sql);

Categories