JDBC Oracle Query. Slow when executing with setInt() instead of setObject() - java

I have the following fragment of code:
public static void main(String[] args) throws SQLException {
Connection c = getConnection();
long time = System.currentTimeMillis();
PreparedStatement ps = c.prepareStatement(sqlQuery);
int index = 1;
for (String param: parameters) {
if (isInt(param)) {
//ps.setInt(index++, Integer.parseInt(param));
ps.setObject(index++, Integer.parseInt(param), java.sql.Types.NUMERIC , 0);
} else {
ps.setString(index++, param);
}
}
displayResult(ps.executeQuery());
System.out.println("It took " + (System.currentTimeMillis()-time) + ".");
time = System.currentTimeMillis();
Statement s = c.createStatement();
ResultSet rs = s.executeQuery(expandParametersInStatement(sqlQuery, parameters));
displayResult(rs);
System.out.println("It took " + (System.currentTimeMillis()-time) + ".");
}
The query executed with a PreparedStatement is slower by a factor of 4000. Compared to the Statement approach. They give the same result and the order of execution makes no huge difference.
Using the setObject() instead of setInt() makes the PreparedStatement as fast as the Statement.
What is the difference? The cast in the Database cannot be that expensive? The data type in the database is a NUMBER(10). I guess it is a matter of the indeces which are used. However, I cannot replicate this in the SQL Developer with CAST(x AS INTEGER)?
Thanks.
The statement is:
private static String sqlQuery = "SELECT sum(value) " +
"FROM a monat, " +
" n jahr, " +
" kunde kunde " +
"WHERE monat.kunde_nr IN " +
" (SELECT DISTINCT kunde.kunde_nr " +
" FROM MASKE_4_KUNDEN kunde " +
" WHERE kunde.firma_nr = ? " +
" AND kunde.verkaufsbereich_nr = ? " +
" AND kunde.vertriebsbereich_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END) " +
" AND kunde.vertreter_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END)" +
" AND kunde.konzern_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END) " +
" AND kunde.geschaeftsjahr = ? " +
" AND kunde.kunde_nr BETWEEN (CASE WHEN ? <> -1 THEN ? ELSE -9999999999 END) AND (CASE WHEN ? <> -1 THEN ? ELSE 9999999999 END))" +
" AND monat.firma_nr = ? " +
" AND monat.verkaufsbereich_nr = ? " +
" AND monat.jahr_nr = ? " +
" AND jahr.kunde_nr = monat.kunde_nr " +
" AND jahr.firma_nr = monat.firma_nr " +
" AND jahr.jahr_nr = monat.jahr_nr " +
" AND jahr.verkaufsbereich_nr = monat.verkaufsbereich_nr " +
" AND kunde.kunde_nr = monat.kunde_nr " +
" AND kunde.firma_nr = monat.firma_nr";

setInt() method receives int as a second parameter (not Integer). now, I know that auto-boxing should work but apparently it doesn't always work: http://www.coderanch.com/t/550628/JDBC/java/setInt-String-int-Lost
My guess is that it didn't work in older versions of JDBC and it works in newer versions but is still buggy...
I would try using Integer.intValue() and see if it works any better!
If anyone has more input in regards - I'd love to hear it!

We observed the same behavior also with a prepared statement having just setString() statements over an Oracle Database 10.2.0.4.0.
The problem has been completely solved updating the jdbc driver from 10.2.0.3.0 to 10.2.0.4.0

Related

create a java process to generate a idempiere report

I have Postgres that works when on it own, but doesn't work when integrated into java and called on idempiere. I'm looking for suggestion.
I get the ff error:
caused by: org.postgresql.util.PSQLException: ERROR: syntax error at or near "00"
Position: 1055; State=42601; ErrorCode=0
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:120)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeUpdate(NewProxyPreparedStatement.java:384)
at jdk.internal.reflect.GeneratedMethodAccessor48.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.compiere.db.StatementProxy.invoke(StatementProxy.java:130)
at com.sun.proxy.$Proxy11.executeUpdate(Unknown Source)
at org.compiere.util.DB.executeUpdate(DB.java:1039)
at org.compiere.util.DB.executeUpdate(DB.java:898)
at org.compiere.util.DB.executeUpdate(DB.java:885)
at ice.enterprise.base.report.StockAgingReport.createDetailLines(StockAgingReport.java:145)
at ice.enterprise.base.report.StockAgingReport.doIt(StockAgingReport.java:72)
at org.compiere.process.SvrProcess.process(SvrProcess.java:201)
at org.compiere.process.SvrProcess.startProcess(SvrProcess.java:147)
at org.adempiere.util.ProcessUtil.startJavaProcess(ProcessUtil.java:173)
at org.compiere.apps.AbstractProcessCtl.startProcess(AbstractProcessCtl.java:467)
at org.compiere.apps.AbstractProcessCtl.run(AbstractProcessCtl.java:235)
15:21:49.994===========> DataEngine.loadPrintData: null - ERROR: column "levelno" does not exist
Position: 924
SQL=SELECT T_ReportStockAgeing.CurrentCost,T_ReportStockAgeing.Date1,T_ReportStockAgeing_ICE.Description,T_ReportStockAgeing.OnHand,(SELECT NVL(AD_PInstance.Name,'-1') ||'_'|| NVL(CAST (AD_PInstance.AD_PInstance_ID AS Text),'-1') ||'_'|| NVL((SELECT NVL(AD_Process.Name,'-1') ||'_'|| NVL(AD_Process.Value,'-1') FROM AD_Process WHERE AD_PInstance.AD_Process_ID=AD_Process.AD_Process_ID),'-1') FROM AD_PInstance WHERE T_ReportStockAgeing.AD_PInstance_ID=AD_PInstance.AD_PInstance_ID) AS AAD_PInstance_ID,T_ReportStockAgeing.AD_PInstance_ID AS AD_PInstance_ID,T_ReportStockAgeing.ProductCode,T_ReportStockAgeing.Qty1,T_ReportStockAgeing.Qty2,T_ReportStockAgeing.Qty3,T_ReportStockAgeing.Qty4,T_ReportStockAgeing.Value1,T_ReportStockAgeing.Valu2,T_ReportStockAgeing.Value3,T_ReportStockAgeing.Value4,T_ReportStockAgeing_ICE.T_ReportStockAgeing_ICE_UU,LevelNo FROM T_ReportStockAgeing_ICE WHERE T_ReportStockAgeing_ICE.AD_PInstance_ID=2109500 [136]
15:21:50.030===========> AbstractProcessDialog.doRun: org.postgresql.util.PSQLException: ERROR: column "levelno" does not exist
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.logging.Level;
import org.compiere.print.MPrintFormat;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.process.SvrProcess;
import org.compiere.util.DB;
import org.compiere.util.Env;
import org.compiere.util.Ini;
public class StockAgingReport extends SvrProcess {
private int p_AD_Org_ID = 0;
private int p_AD_Client_ID = 0;
private int p_C_AcctSchema_ID = 0;
private int p_M_Product_Category_ID = 0;
private Timestamp p_Date = null;
private long m_start = System.currentTimeMillis();
#Override
protected void prepare() {
StringBuffer sb = new StringBuffer ("Record_ID=")
.append(getRecord_ID());
// Parameter
ProcessInfoParameter[] para = getParameter();
for (int i = 0; i < para.length; i++)
{
String name = para[i].getParameterName();
if (para[i].getParameter() == null && para[i].getParameter_To() == null)
;
else if (name.equals("Date"))
{
p_Date = (Timestamp)para[i].getParameter();
}
else if (name.equals("AD_Org_ID"))
p_AD_Org_ID = ((BigDecimal)para[i].getParameter()).intValue();
else if (name.equals("AD_Client_ID"))
p_AD_Client_ID = para[i].getParameterAsInt();
else if (name.equals("C_AcctSchema_ID"))
p_C_AcctSchema_ID = para[i].getParameterAsInt();
else if (name.equals("M_Product_Category_ID"))
p_M_Product_Category_ID = para[i].getParameterAsInt();
else
log.log(Level.SEVERE, "Unknown Parameter: " + name);
}
log.fine(sb.toString());
}
#Override
protected String doIt() throws Exception {
createDetailLines();
int AD_PrintFormat_ID = DB.getSQLValue(get_TrxName(), "Select AD_PrintFormat_ID from AD_PrintFormat Where name = 'Stock_Ageing'");
if (AD_PrintFormat_ID > 0) {
if (Ini.isClient())
getProcessInfo().setTransientObject (MPrintFormat.get (getCtx(), AD_PrintFormat_ID, false));
else
getProcessInfo().setSerializableObject(MPrintFormat.get (getCtx(), AD_PrintFormat_ID, false));
}
if (log.isLoggable(Level.FINE)) log.fine((System.currentTimeMillis() - m_start) + " ms");
return "";
}
private void createDetailLines() {
StringBuffer sb = new StringBuffer ("INSERT INTO T_ReportStockAgeing "
+ "(AD_PInstance_ID, AD_Client_ID, AD_Org_ID, ProductCode, Description, CurrentCost,"
+ " Qty1, Qty2, Qty3, Qty4, OnHand,"
+ " Value1, Valu2, Value3 ,Value4) ");
sb.append("SELECT ").append(getAD_PInstance_ID()).append(", ").append(Env.getAD_Client_ID(getCtx())).append(", ").append(Env.getAD_Org_ID(getCtx())).append(", ")
.append( "ProductCode, Description, Case OnHand WHEN 0 THEN 0 ELSE CurrentCost*OnHand END AS CurrentCost,"
+ "Qty1, Qty2, Qty3, Qty4, OnHand,"
+ "CASE OnHand WHEN 0 THEN 0 ELSE round((CurrentCost) * Qty1,2) END as Value1, "
+ "CASE OnHand WHEN 0 THEN 0 ELSE round((CurrentCost) * Qty2,2) END as Valu2, "
+ "CASE OnHand WHEN 0 THEN 0 ELSE round((CurrentCost) * Qty3,2) END as Value3, "
+ "CASE OnHand WHEN 0 THEN 0 ELSE round((CurrentCost) * Qty4,2) END as Value4 "
+ "FROM ( "
+ "SELECT "
+ "prod.value as ProductCode, "
+ "prod.description as Description, "
+ "M_Product_Category_ID, "
+ "(SELECT COALESCE (max(c.CurrentCostPrice),0) FROM M_Cost c WHERE c.AD_Org_ID =" +p_AD_Org_ID +" AND c.C_AcctSchema_ID= "+p_C_AcctSchema_ID+" AND prod.M_Product_ID = c.M_Product_ID AND prod.ProductType !='A' ) as CurrentCost, "
+ "(SELECT COALESCE (SUM (st.qtyonhand),0)FROM M_Storage st "
+ "WHERE prod.M_Product_ID = st.M_Product_ID "
+ "AND st.DateMaterialPolicy >= ( ("+p_Date+"::date) - interval '3 month' ) "
+ "AND st.DateMaterialPolicy <= ("+p_Date+"::date) "
+ "AND st.AD_Org_ID = "+p_AD_Org_ID+" AND prod.ProductType !='A' "
+ ") as Qty1, "
+ "(SELECT COALESCE (SUM (st.qtyonhand),0)FROM M_Storage st "
+ "WHERE prod.M_Product_ID = st.M_Product_ID "
+ "AND st.DateMaterialPolicy >= ("+p_Date+"::date- interval '6 month' ) "
+ "AND st.DateMaterialPolicy <= ("+p_Date+"::date - interval '3 month') "
+ "AND st.AD_Org_ID = "+p_AD_Org_ID+" AND prod.ProductType !='A') "
+ "as Qty2, "
+ "(SELECT COALESCE (SUM (st.qtyonhand),0)FROM M_Storage st "
+ "WHERE prod.M_Product_ID = st.M_Product_ID "
+ "AND st.DateMaterialPolicy >= ("+p_Date+"::date - interval '12 month' ) "
+ "AND st.DateMaterialPolicy <= ("+p_Date+"::date- interval '6 month') "
+ "AND st.AD_Org_ID = "+p_AD_Org_ID+" AND prod.ProductType !='A' "
+ ") as Qty3, "
+ "(SELECT COALESCE (SUM (st.qtyonhand),0)FROM M_Storage st "
+ "WHERE prod.M_Product_ID = st.M_Product_ID "
+ "AND st.DateMaterialPolicy < ("+p_Date+"::date- interval '12 month') "
+ "AND st.AD_Org_ID = "+p_AD_Org_ID+" AND prod.ProductType !='A' "
+ ") as Qty4, "
+ "(SELECT COALESCE (SUM (st.qtyonhand),0)FROM M_Storage st "
+ "WHERE prod.M_Product_ID = st.M_Product_ID "
+ "AND st.AD_Org_ID = "+p_AD_Org_ID+" AND prod.ProductType !='A' "
+ ") as OnHand "
+ "FROM M_Product prod "
+ "LEFT JOIN AD_Org org ON org.AD_Org_ID = "+p_AD_Org_ID+" "
+ "LEFT JOIN M_Product_Category prodcat ON prodcat.M_Product_Category_ID = "+p_M_Product_Category_ID+" AND prodcat.AD_Client_ID = "+p_AD_Client_ID+" "
+ "WHERE prod.M_Product_Category_ID = "+ p_M_Product_Category_ID+" AND prod.ProductType !='A' "
+ ")temp ");
sb.append(" ) as temp ");
int no = DB.executeUpdate(sb.toString(), get_TrxName());
log.fine("#" + no);
log.finest(sb.toString());
}
}
I tried to integrate your class example for testing in iDempiere, but as GhostCat pointed, it's better if you create a minimal reproducible example, and also very important, please post also the error that is being thrown by the system, in UI and/or in console log.
The class doesn't have some imports, all the variables are not used, and the private method createDetailLines is never called, I assume the error you're mentioning is in that method, but there is no way to know if is not called.
Now, reviewing the SQL, there are two things to notice:
1 - it's not formatted for java, you use "AND c.C_AcctSchema_ID= $P{C_AcctSchema_ID}" and that's not the way as java manage variables, that sounds like jasper report syntax instead of java. For JDBC you must use ? as a replacement for binding variables
2 - iDempiere is multi-database, the way how the system is designed is to write oracle compatible SQL syntax, and there is a translation layer that converts the oracle statement ot postgresql syntax. So, it's better to avoid using postgresql specific syntax like "::date" or interval '3 month' - it could work, but it can also have problems with the convert layer. If you want to use specific postgresql syntax and avoid the convert layer being confused you can surround the postgresql specific syntax with NATIVE_PostgreSQL_KEYWORK - please don't blame me about the error in this constant :-)

HQL with case, sum e max

I have a query that is giving problem, I believe the problem occurs because it does not allow to use the max function, inside the max function, am I correct?
How can I get around this? I need to add all values ​​except for the last row.
The query:
"SELECT new project.domain.vo.MediaPagVo(" +
"a.nomeUsuario, " +
"a.cpfUsuario, " +
"a.cnpjUnidadeUsuario, " +
"a.nomeUnidadeUsuario, " +
"a.codigoGrupoUsuario, " +
"a.grupo.id AS idGrupo, " +
"CASE " +
"WHEN MAX(a.pre) - MIN(a.pre) > 0 " +
"THEN ((MAX(a.pre) - MIN(a.pre)) / SUM(CASE WHEN max(a.dtRequisicao) > a.dtRequisicao THEN a.valorTotal ELSE 0 END)) " +
"ELSE ((MAX(a.pos) - MIN(a.pos)) / SUM(CASE WHEN max(a.dtRequisicao) >= a.dtRequisicao THEN a.valorTotal ELSE 0 END)) " +
"END AS mediaConsumo, " +
"CASE " +
"WHEN MAX(a.pre) - MIN(a.pre) > 0 " +
"THEN " + Tipo.PRE.getValue() + " " +
"ELSE " + Tipo.POS.getValue() + " " +
"END AS tipoPag) " +
"FROM " +
" Pagamento a " +
"WHERE " +
"a.status = " + StatusPagamento.Concluido.getValue() + " AND " +
"a.dataRequisicao BETWEEN :inicio and :fim AND " +
"( :idGrupo IS NULL OR a.grupo.id = :idGrupo) " +
"GROUP BY " +
" a.nomeUsuario, a.cpfUsuario, a.cnpjUnidadeUsuario, a.nomeUnidadeUsuario, a.codigoGrupoUsuario, a.grupo.id, " +
"HAVING (MAX(a.pos) - MIN(a.pos) > 0 OR MAX(a.pre) - MIN(a.pre) > 0) AND " +
"( :tipoConsumo IS NULL OR " +
":tipoConsumo = " + Tipo.PRE.getValue() + " AND " +
"(MAX(a.pre) - MIN(a.pre) > 0) " +
"OR :tipoConsumo = " + Tipo.POS.getValue() + " AND " +
"(MAX(a.pos) - MIN(a.pos) > 0) ) ";
The error began to occur after I modified this section, adding the case inside the sum:
"CASE WHEN MAX(a.pre) - MIN(a.pre) > 0 " +
"THEN ((MAX(a.pre) - MIN(a.pre)) / SUM(CASE WHEN max(a.dtRequisicao) > a.dtRequisicao THEN a.valorTotal ELSE 0 END)) " +
"ELSE ((MAX(a.pos) - MIN(a.pos)) / SUM(CASE WHEN max(a.dtRequisicao) >= a.dtRequisicao THEN a.valorTotal ELSE 0 END)) " +
"END AS mediaPag, "
The error returned by java:
Could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
ORA-00937: not a single-group group function tips
My goal was to add up all the payments for that period, minus the last. Unfortunately, I could not just move the filter, since max (a.pre), max (a.pos) may be the last payment. Does anyone have any ideas?
Maybe it is also worth asking how to refactor this query. Is performance a problem? I mean instead of running one query you would run several smaller ones would the system be very slow.
For ex. get MIN MAX(a.pre) in a separate query, do the SUM(CASE WHEN in Java code and pass these values as parameters.
If you decide to refactor, it would be safe to first add some tests to see the behaviour of the old query with certain values. Then do the refactoring. And finally, re-run the tests you added to check that you didn't add any bug.

How to write prepared statements for this query?

Hi i have written a join query for my app and its working. My next requirement is to convert that query to prepared statement where I am stuck.
"SELECT * FROM " + TableA.TABLE + " as d LEFT JOIN " + TableB.TABLE + " as c ON d."+ TableA.DAMAGECODE + "=c." + TableB.DAMAGECODE + " AND d."
+ TableA.INDEX + "=c." + TableB.DAMAGECODEINDEX + " AND d."
+ TableA.OBJECTTYPE + "=c." + TableB.OBJECTCLASS + " WHERE d."+ TableA.LEAF + " = '1' AND d." + TableA.OBJECTTYPE + " = ? AND " + "(d."+ TableA.DAMAGECODE + " LIKE ? OR d." + TableA.DAMAGETEXT + " LIKE ?) AND c." + TableB.CONSTRUCTIONSERIES + " = ? ORDER BY " + TableA.DAMAGETEXT;
cursor = db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
When i ran raw query i am getting results ,but when ran the above prepared statements i am getting cursor count always zero
You don't need to add the ' yourself when you pass a String parameters, the PreparedStatement will manage those itself.
"'%" + query + "%'"
For the moment you have condition like
where columnA = "'%somethingToFind%'"
So unless you have a value in columnA like 'somethingToFindInColumnA' (note the quote at the begin and the end of that String). You will never get a result.
Remove those to get something like :
"%" + query + "%"
Full answer :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"'%" + query + "%'","'%" + query + "%'",constructionSeries});
Become :
db.rawQuery(sql,new String[]{String.valueOf(objectClass),"%" + query + "%","%" + query + "%",constructionSeries});

How to insert NULL in mysql especially INT dataType

I have 80000 recodes that are need to insert into database especially in table: temp(ts, temp)
temp is INT.
The problem is almost 20000 recodes are null, so I am wondering how to insert NULL into DB when dataType is INT.
I tried this:
String val = null;
//insert(ts, val) into temp
String sql = "INSERT INTO temp" + "(val)" + " VALUES" + "('" + val + "')";
Statement st = (Statement) conn.createStatement();
count = st.executeUpdate(sql);
unfortunately insert is failure. Print out the exception message:
Incorrect integer value: 'null' for column 'val' at row 1"
Wish someone can help me with it. Thank you.
You should use a PreparedStatement and use setNull(int, int):
String sql = "INSERT INTO temp(val) VALUES (?)";
PreparedStatement st = con.prepareStatement(sql);
if (/* int value is not null */) {
st.setInt(1, value);
} else {
set.setNull(1, Types.INTEGER);
}
count = st.executeUpdate();
As an alternative to Mark Rotteveel's answer, you can also use PreparedStatement.setObject(int, Object, int).
You specify the SQL Type (3rd Parameter), and if the object is null, it inserts a null automatically. It's faster and easier.
String sql = "INSERT INTO temp(val) VALUES (?)";
PreparedStatement st = con.prepareStatement(sql);
st.setObject(1, value, Types.INTEGER);
count = st.executeUpdate();
You should consider using prepared statements. If you do, you'll find information on how to deal with nulls here and elsewhere.
If you're 100% sure your val value is clean and won't cause SQL Injection (rare, but possible), then the "built string" approach needs to explicitly use null when defining the value:
String sql = "INSERT INTO temp (val) VALUES (";
if (val == null) {
sql += "null";
} else {
sql += val;
}
sql += ")";
I have solved this problem.
The codes update as following:
String sql= null;
if(val.isEmpty()){
System.out.println(val);
System.out.println("Insert ts: " + ts + " val: null");
sql= "INSERT INTO " + table + "(ts,val,pointId)" + " VALUES" + "(" + "'" + ts + "'" + ", " + "NULL" + " , " + "'" + pointId + "'" + ")";
}
else{
System.out.println("Insert ts: " + ts + " val: " + val);
sql= "INSERT INTO " + table + "(ts,val,pointId)" + " VALUES" + "(" + "'" + ts + "'" + ", " + "'" + val + "'" + ", " + "'" + pointId + "'" + ")";
}
Statement st = (Statement) conn.createStatement(); //create the instances of statement
count = st.executeUpdate(sql);
Basically, if insert null into database, just do insert into table(val) value(NULL).
You should explicitly CAST the NULL as an INT
...VALUES(...CAST(NULL AS INT)
It sounds like your are sending "null" in when you should be sending an int. Perhaps try something like
(val == null ? "" : val)

create and insert values using mysql JDBC

I have the sample code.
public void UpdateTable1() {
for (int t = 0; t < 20; t++) {
if (consumer == 1 && number == 1 && provider1 == 31 && feedback == 1) {
try {
Class.forName(driverName);
con = DriverManager.getConnection(url + dbName, "root", "mysql");
try {
Statement st = con.createStatement();
int val = st.executeUpdate("INSERT Consumer1 VALUES ("
+ 31 + "," + "'Printer'" + ", " + 1 + " " + ")");
System.out.println("1 row affected");
} catch (SQLException s) {
System.out.println("SQL statement is not executed!");
}
con.close();
}
}
}
}
I want to insert the same set of values(31,printer,1) into the table consumer2,consumer3.Is it possible without using another try catch statements...Please help me.
I hope I'm not offending, but are you sure you fully understand how try-catch works?
The reason that the try catch statement is inside the for for t loop, is (likely) that someone wanted to ensure that one failure will not prevent other iterations of the loop from taking place. You could end up with corrupted data that way.
The decision you have to make is whether you want to do all three insertions under the same try-catch or not.
To easily do three insertions, do a loop on i from 1 to 3, and every time create a different statement, by adding strings, so that the first time the table is Consumer1, the second time it is Consumer2, etc. Put the whole loop inside the try catch, or put the-try-catch inside the body of the loop.
You could replace
"INSERT Consumer1 VALUES ("
with
"INSERT INTO Consumer" + (t + 1) + " VALUES ("
I'm a little unclear on this one. Is there some restriction on how many statements you can create per connection? Or will the connection close down after each update is executed?
If not, then this should work
Statement st2 = con.createStatement();
int val = st.executeUpdate("INSERT Consumer2 VALUES ("+ 31 + "," + "'Printer'" + ", " + 1 + " " + ")");
Statement st3 = con.createStatement();
int val = st.executeUpdate("INSERT Consumer3 VALUES ("+ 31 + "," + "'Printer'" + ", " + 1 + " " + ")");
if the connection closes down or you can only do one statement at a time, then I guess you could move the whole thing to a private method and then call it with different parameters, something like:
private boolean doInsert(String tableName) {
con = DriverManager.getConnection(url + dbName, "root", "mysql");
try {
Statement st = con.createStatement();
int val = st.executeUpdate("INSERT " + tableName + " VALUES ("
+ 31 + "," + "'Printer'" + ", " + 1 + " " + ")");
System.out.println("1 row affected");
return true;
} catch (SQLException s) {
System.out.println("SQL statement is not executed!");
return false;
}
}

Categories